2011-08-27 2 views
4

나는 Comparable을 취하여 Comparable을 반환하고 같은 일을하는 다른 메서드를 래핑합니다.뷰 바운드가 상위 유형 바인딩과 호환되지 않습니까?

def myMethod[T <: Comparable[T]](arg: T): T = otherMethod(arg) 
def otherMethod[T <: Comparable[T]](arg: T): T = arg 

이 함수는 컴파일되지만 Int 또는 다른 형식의 myMethod를 호출 할 수 없습니다. Comparable를 구현하려면 암시 ​​적 변환이 필요합니다. 내가 이해하기 때문에 뷰 경계는 이러한 유형의 문제를 해결하기위한 것이지만 뷰 바인딩을 사용합니다.

컴파일러 오류가 발생합니다.

inferred type arguments [T] do not conform to method otherMethod's type parameter bounds [T <: java.lang.Comparable[T]]

지금까지 유일한 해결 방법은 두 번째 형식 매개 변수를 사용하여 두 형식 사이에 캐스팅하는 것입니다.

def myMethod[T <% Comparable[T], U <: Comparable[U]](arg: T): T = 
    otherMethod(arg.asInstanceOf[U]).asInstanceOf[T] 

이 방법은 효과가 있지만보기 흉합니다. 더 좋은 방법이 있습니까?

답변

6

다음 중 하나를 사용할 수 있습니까?

  1. ,

    def otherMethod[T <% Comparable[T]](arg: T): T = arg 
    def myMethod[T <% Comparable[T]](arg: T): T = otherMethod(arg) 
    
  2. 는 새로운 유형의 매개 변수 U <: Comparable[U]U-T에서 암시 적 변환을 소개 두 방법 모두에서 일관된 바인딩 T의 견해를 확인

    def otherMethod[T <: Comparable[T]](arg: T): T = arg 
    def myMethod[U <: Comparable[U], T <% U](arg: T): U = otherMethod(arg) 
    

버전에 따른 문제 예를 들어, T <% Comparable[T]TComparable[T]으로 변환하지만 이는 (의사 코드) 인 otherMethod이 만족할만한 재귀 유형을 충족시키지 못합니다.


업데이트. 스칼라의 IntotherMethod 또는 myMethod 중 하나를 사용하려면

myMethod(2)     // Int value types don't implement Comparable 
myMethod(2: java.lang.Integer) // Apply implicit conversion (Int => java.lang.Integer) 

가 업데이트 2, 조금 inferencer 유형을 수 있도록해야합니다. 코멘트에서, 당신은 myMethod을 호출 사이트에서 타입 유추를 개선하기 위해 약간 못 생기게하고 싶다고 말했습니다. ev1 실제로 적용됩니다 및 ev2는 원조 형식 유추에있다 : 여기

def myMethod[U <: Comparable[U], T](arg: T) 
    (implicit ev1: T => U, ev2: T => Comparable[U]): U = otherMethod(arg) 
myMethod(2) // returns java.lang.Integer(2) 

비결은 두 암시 적 변환을 사용하는 것입니다 방법입니다. 후자는 스칼라가 impl30에서 Int => Comparable[U] 유형의 변환을 검색해야합니다. 이 경우 변환은 하나만 발견되어 U = java.lang.Integer을 수정합니다.

그런데이 코드를 scalac -Xprint:typer으로 컴파일 해보십시오. 동일한 암시 적 값인 Predef.int2Integerev1ev2 매개 변수에 모두 사용됩니다.

사이드 노트 : asInstanceOf 캐스트는 스칼라 유형 시스템의 건전성을 저해하기 때문에 피하기가 가장 좋습니다.

+0

1. 아니요, 불행히도 otherMethod는 제 3 자 라이브러리에 정의되어 있습니다. 2. 예! 이것은 작동하는 것 같습니다. 감사! – ethzero

+0

도와 줘서 기쁩니다 :-) –

+0

사실 저는 너무 빨리 말했습니다 ... 두 번째 해결책은 컴파일되지만 Int로 호출 할 수는 없습니다. 여기에 오류가 있습니다 : "유형 인수 [Int, Int]가 메소드 myMethod의 유형 매개 변수 경계 [U <: java.lang.Comparable [U], T]에 일치하지 않습니다." – ethzero

관련 문제