2013-02-16 2 views
3

TypeTags 만 호출 메서드의 매개 변수에 사용되는 형식 매개 변수에 대한 작업, 그리고 반환 형식 보인다 :반환 유형에 대해 TypeTag가 작동하지 않는 이유는 무엇입니까?

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

import scala.reflect.runtime.universe._ 

object Test { 
    def withParam[T: TypeTag](v: T): T = { 
    println(typeOf[T]) 
    0.asInstanceOf[T] 
    } 

    def justReturn[T: TypeTag](): T = { 
    println(typeOf[T]) 
    0.asInstanceOf[T] 
    } 
} 

// Exiting paste mode, now interpreting. 

import scala.reflect.runtime.universe._ 
defined module Test 


scala> val i: Int = Test.withParam(17) 
Int 
i: Int = 0 

scala> val j: Int = Test.justReturn() 
Nothing 
j: Int = 0 

이 2.9에서 매니페스트의 동작과 일치하지만,이 모든입니다 그 이유는 할 수 없으며,이 효과를 얻기위한 다른 방법이 있습니까?

+1

그 밖의 무엇을 할 수 있습니까? 즉,'justReturn'이 반환 할 내용은 무엇입니까? –

답변

2

타입 시스템은 가장 제한적인 타입 (예 : Nothing)으로 시작합니다.이 중 인스턴스는 존재할 수 없으며, 존재한다면 신의 가치를 지니고 무엇이든 할 수 있습니다. 그런 다음 유형은 필요에 따라 넓혀 지지만 반품은 반공 위치에 있으므로 절대 넓힐 이유가 없습니다. 실제로 Nothing을 반환 할 수있는 경우 모든 상황에서 설정할 수 있습니다.

그런 다음 0Nothing의 인스턴스임을 입력하여 유형 시스템을 파괴합니다. 물론 완전히 거짓입니다.하지만 컴파일러는 충실히 당신을 믿습니다. 그리고 그 상황을 실제로 Int에 할당하여 상황을 구조합니다. (또한 String에 행복하게 할당하려고하면 런타임에 예외가 발생하게됩니다. 그 이유는 무의미합니다.)

이론적으로 이것은 다르게 수행 될 수 있지만 이것은 매우 기본적인 부분입니다 타입 추론 알고리즘

+1

사실 'Int'가 아닌 명시적인 타입 매개 변수로 원본'justReturn'을 호출하면 컴파일 타임 오류가 발생합니다. 흥미롭게도 "weak conformance"를 통해 'Int'와 호환되는 명시적인 타입 매개 변수를 주면 런타임에 오류가 발생합니다. 예 :'Test.justReturn [Byte]()'java.lang.ClassCastException : java.lang.Integer를 java.lang.Byte'로 형변환 할 수 없습니다. –

+0

@RandallSchulz - 나는 모든 경우에'ClassCastExceptions'를 얻습니다. 어떤 버전을 사용하고 있습니까? (2.10.0 here.) –

+0

이것이 알고리즘이 작동하는 방법이라면 그 의미가 있습니다. 감사. – Yan

2

Rex Kerr의 의견을 확대하면 justReturn 경우에는 T의 드라이브 추론이 없습니다. 당신이 (적합)를 입력 매개 변수를 제공하는 경우, 당신이 얻을 :

scala> val j: Int = Test.justReturn[Int]() 
Int 
j: Int = 0 

을이에 justReturn을 변경하는 경우 :

def justReturn[T: TypeTag]() { 
    println(typeOf[T]) 
} 

을 ... 당신은이 작업을 수행 할 수 있습니다

scala> justReturn[String]() 
String 

scala> justReturn[java.io.File]() 
java.io.File