은의가 몇 관찰을하고 반환 형식을 결정하도록 컴파일러시키기의 몇 가지 방법으로 실험 해보자 if
문은 then 및 else 절에서 과 동일한 유형을 반환해야합니다. 따라서이 문이 값을 반환하면 컴파일러는 일반 유형을 추론하여 두 개의 절에 일관된 제약 조건을 적용해야합니다. 당신이 예를 a[scala.io.Source]()
를 들어, a()
를 호출 할 때
2) T
변수 유형을 알 수는 당신이 통과 정확한 유형에 따라 달라집니다. 메소드 선언에서 T
에 상한값 인 T <: AnyRef
을주었습니다. 이는 컴파일러가 AnyRef 및 Option [String]의 부속 유형 인 모든 유형의 합집합 인 가장 일반적인 유형을 찾아야 함을 의미합니다.
3) 반환 형식 선언을 제거하여 컴파일러에서 유추되는 반환 형식을 확인하십시오. 즉 def a[T <: AnyRef]() = if (true) List[T]() else List[Option[T]]()
입니다. 컴파일러에서 a()
반환 유형 List[AnyRef]
을 제공했습니다. 이 유형은 의미가 있습니다. 서브 유형이 AnyRef
이고 Option[of that anything T]
인 T
사이의 가장 일반적인 유형에 대한 유일한 가능성 때문입니다.
4) 이제 시도하십시오 def a[T <: AnyRef]() = if (true) List[T]() else List[Option[String]]()
. 추론 된 반환 유형은 이제 List[java.lang.Object]
입니다. 그 이유는 스칼라 2.8의 String
클래스가 실제로 java.lang.String
이기 때문에 가장 일반적인 추측에 따르면 가장 일반적인 유형은 scala.*
계층을 벗어나 알려지지 않은 이유로 java.lang.Object
으로 끝납니다. AnyRef
이후
5) 정말 java.lang.Object
단지 별칭, 당신은 List[AnyRef]
의 반환 유형을 강제로 def a[T <: AnyRef](): List[AnyRef] = if (true) List[T]() else List[Option[String]]()
할 수 있습니다. 기본적으로 슈퍼 클래스를 반환
def a(): List[AnyRef] = ...
을, 당신은 .asInstanceOf[T]
를 사용하여 아래로 돌려 List[AnyRef]
캐스팅해야한다 : 당신은 그냥 AnyRef의 하위 유형을 반환하려면
, 당신은 기본적으로이 작업을 수행 할 수 있습니다.또한 :
def a[T <: AnyRef](): List[T] = List[T]()
의지는 당신에게 특정 유형 (T)를 제공하지만, 하나 더 구체적이고 다른 수 있습니다 귀하의 예제에서와 같은 if
문에 2 개 개의 다른 형태를 돌려, 항상 그것을 기대할 수 없다 메소드를 호출 할 때 사용자가 제공 한보다 구체적인 유형을 리턴하십시오. 컴파일러는 형식을 보장 할 방법이 없으므로 if
문은 형식 검사만으로 항상 List [T]가됩니다. 나는 그것을 더 명확하게 만들었습니까?
컴파일러가 원하는 것을 알아낼 수없는 경우 추가 설명없이 어떻게 알아 내야합니까? –
인터프리터에 입력하여 알아낼 수 있습니다. –
내 대답 편집을 마쳤습니다. 그것이 너무 많은지 알려주세요 :) –