이름 별 전화 : => 유형
이 => Type
표기법은 이름 별 호출을 나타내며 매개 변수를 전달할 수있는 많은 방법 중 하나입니다 . 익숙하지 않다면 요즘 위키 백과 기사를 읽어 보는 것이 좋습니다. 요즘은 대부분의 가치 별 기준이며 기준 별 기준입니다.
의미는 전달 된 것이 함수 내부의 값 이름으로 대체 된다는 것입니다 . 예를 들어 다음 기능을 사용하십시오.
def f(x: => Int) = x * x
이렇게 전화하면
var y = 0
f { y += 1; y }
그런 다음 코드는 다음과 같이 실행됩니다
{ y += 1; y } * { y += 1; y }
식별자 이름 충돌이 발생하면 어떤 일이 발생하는지 지적합니다. 기존의 이름 별 통화에서는 이름 충돌을 피하기 위해 캡처 방지 대체라는 메커니즘이 사용됩니다. 그러나 Scala에서는 동일한 결과로 다른 방식으로 구현됩니다. 매개 변수 내의 식별자 이름은 호출 된 함수의 식별자를 참조하거나 섀도 잉 할 수 없습니다.
다른 두 가지를 설명한 후에 언급 할 이름 별 통화와 관련된 몇 가지 다른 점이 있습니다.
0-arity 함수 : () => Type
구문 () => Type
은의 유형을 나타냅니다 Function0
. 즉, 매개 변수를 사용하지 않고 무언가를 반환하는 함수입니다. 이는 메서드를 호출하는 것과 같습니다 size()
. 매개 변수를 사용하지 않고 숫자를 반환합니다.
그러나이 구문은 익명 함수 리터럴 의 구문과 매우 유사하다는 점이 흥미 롭습니다. 이는 혼동의 원인이됩니다. 예를 들어
() => println("I'm an anonymous function")
arity 0의 익명 함수 리터럴이며 유형 은
() => Unit
그래서 우리는 쓸 수 있습니다 :
val f: () => Unit = () => println("I'm an anonymous function")
그러나 유형과 값을 혼동하지 않는 것이 중요합니다.
단위 => 유형
이것은 실제로 단지 Function1
첫 번째 매개 변수 유형 Unit
입니다. 작성하는 다른 방법은 (Unit) => Type
또는 Function1[Unit, Type]
입니다. 문제는 ... 이것이 원하는 것이 아닐 것입니다. Unit
유형의 주요 목적은 그래서 이해가되지 않습니다에 관심되지 않은 값을 표시한다 받을 그 값을.
예를 들어,
def f(x: Unit) = ...
무엇을 할 수 x
있습니까? 단일 값만 가질 수 있으므로받을 필요가 없습니다. 가능한 함수 중 하나는 다음을 반환하는 체인 함수입니다 Unit
.
val f = (x: Unit) => println("I'm f")
val g = (x: Unit) => println("I'm g")
val h = f andThen g
에 andThen
정의되어 Function1
있고 우리가 연결하는 함수가 반환되고 있기 때문에이를 연결 시킬 수 Unit
있는 유형으로 정의해야 Function1[Unit, Unit]
했습니다.
혼란의 근원
혼동의 첫 번째 원인은 0-arity 함수에 존재하는 유형과 리터럴의 유사성이 이름 별 호출에도 존재한다고 생각하는 것입니다. 다시 말해,
() => { println("Hi!") }
의 리터럴입니다 () => Unit
.
{ println("Hi!") }
의 리터럴이됩니다 => Unit
. 그렇지 않습니다. 그것은 리터럴이 아닌 코드 블록입니다 .
혼동의 또 다른 원인은 Unit
type 값 이 ()
0-arity 매개 변수 목록처럼 보이지만 그렇지 않다는 것입니다.
case class Scheduled(time: Int)(callback: => Unit)
. 보조 매개 변수 목록이 공개적으로 노출되지 않았거나 생성 된equals
/hashCode
메소드에 포함되지 않았기 때문에 작동 합니다.