2016-10-09 2 views
3

어디에도 함수 ev을 정의하지 않았습니다. 그렇다면 아래 코드가 어떻게 작동합니까? 함축 된 용어가 사용 범위에 정의되어 있지 않아야합니까?암시 적 함수를 정의하지 않고 전달 및 사용

scala> import scala.reflect.runtime.universe.{ reify, showCode } 
import scala.reflect.runtime.universe.{reify, showCode} 

scala> def same[T, U](x: U)(implicit ev: U => T): T = ev(x) 
same: [T, U](x: U)(implicit ev: U => T)T 

scala> showCode(reify(same(2)).tree) 
res0: String = $read.same(2)(Predef.$conforms) 

그래서 ev에 의해 제공됩니다

def same[T, U](x: U)(implicit ev: U => T): T = {ev(x)} 
same(2) // 2 
+2

@TravisBrown 대답을 확장하려면'Int [Long, Int] (2)'를 수행하면'Int'에 정의 된 암시 적으로 호출되는 'int2long'이 정의되어 있기 때문에 여전히 컴파일된다는 것을 알 수 있습니다. 이 일. 이와 같은 마법이 일어날 때, 어떤 implicits가 당신에게 명시 적으로 적용되는지 생각해보십시오. 명시 적으로 그들에게 요청합니다. –

+0

감사합니다 Yuval, 혼란스러운 부분은 컴파일러가'T'를 추론 할 때 (암시 적으로 검색하기 전에)입니다. 이것은 암시적인 $ conforms 메소드가있는 첫 번째 브러시입니다. – Samar

답변

5

이 같은 질문이있을 때마다, 시작하기에 좋은 장소는 무슨 일이 일어나고 있는지 컴파일러를 요청하기 위해 REPL에서 스칼라 반사 API를 사용하는 것입니다 Predef.$conformsA에 대해 A <:< A의 인스턴스를 제공하는 암시 적 메서드입니다. 여기서 <:<Function1입니다.

그래서 단서가 있습니다. 나머지를 알아 내려면 형식 유추에 대해 조금 생각해야합니다. same(2)을 호출하면 컴파일러는 식 2의 형식이 Int이고 그 값은 UInt이라고 추정합니다. 다음으로는 T이 무엇인지 알아 내야하고, 어떤 유형의 에 대해 Int에서 x까지의 암시 적 함수를 찾으려고합니다.

$conforms이 들어오는 곳은.입니다 컴파일러가 ev 유형 Int => Int이며 TInt 수 있으며, 작업이 완료 즉, 그것을 선택 그래서, 범위에서 그러한 방법입니다.

+0

그것은 깔끔한 반사 묘기입니다. 나는 항상'scalac -Xprint..'를 사용하여 나무를 본다. –

+0

@YuvalItzchakov 그래,'scalac -Xprint'도 유용 하긴하지만, 이런 식으로 자급 자족 한 예제에서는 잡음이 적고 편리하지 않다. –

+0

확실히 더 많은 소음이 들어옵니다. 나는 이것을 기억할 것입니다 :) –