2010-02-25 3 views
11

일반 형식 매개 변수를 null 입력 가능 형식으로 제한하는 두 가지 방법을 시도했지만 두 가지 모두 예상치 못한 문제가있는 것 같습니다.nullable 형식에 대한 scala 일반 제약 조건의 작동 방법

첫 번째 시도 (T < 사용 : AnyRef) :

scala> def testAnyRefConstraint[T <: AnyRef](option:Option[T]):T = { 
    | //without the cast, fails with compiler error: 
    | // "found: Null(null) required: T" 
    | option getOrElse null.asInstanceOf[T] 
    | } 
testAnyRefConstraint: [T <: AnyRef](Option[T])T 

scala> testAnyRefConstraint(Some("")) 
res0: java.lang.String = 

scala> testAnyRefConstraint(Some(0)) 
<console>:16: error: inferred type arguments [Int] do not conform to method testAnyRefConstraint's type parameter bounds [T <: AnyRef] 
     testAnyRefConstraint(Some(0)) 

이 내가 원하는 것을 정확히 할 것 같지만 널은 T.

에 캐스트 할 필요가 왜 이해가 안가

두 번째 시도 (사용 T> : 널) : 이것은 널 (null)에 캐스팅을 필요로하지 않습니다

scala> def testNullConstraint[T >: Null](option:Option[T]):T = { 
    | option getOrElse null 
    | } 
testNullConstraint: [T >: Null](Option[T])T 

scala> testNullConstraint(Some("")) 
res2: java.lang.String = 

scala> testNullConstraint(Some(0)) 
res3: Any = 0 

하지만, AnyVals를 전달하고 유형을 any로 변환합니다. 이는 내가 찾던 것이 아닙니다.

왜이 두 가지 접근 방식이 다른 방식으로 작동하는지 알 수있는 사람이 있습니까?

답변

20
def testAnyRefConstraint[T >: Null <: AnyRef](option:Option[T]):T = { 
    option getOrElse null 
} 

나는이 오류를 처음 만들었을 때 정말 어리 석었다. 무언가가 AnyRef을 확장한다고해서 그것이 nullable이어야한다는 것을 의미하지는 않습니다. 예를 들어 NothingAnyRef의 하위 유형이며 Null을 허용하지 않습니다.

AnyNull의 수퍼 유형이고 IntAny이기 때문에 다른 방법도 비슷합니다.

관련 문제