2011-04-11 2 views
3

와 혼동 : 나무 상자는 불변이기 때문에다음 감안할 때 분산

trait Fruit 

class Apple extends Fruit 
class Orange extends Fruit 

case class Crate[T](value:T) 

def p(c:Crate[Fruit]) { } 

val cra = Crate(new Apple) 
val cro = Crate(new Orange) 

가, 내가 할 수없는 (예상대로) 다음

scala> val fruit:Crate[Fruit] = cra 
<console>:10: error: type mismatch; 
found : Crate[Apple] 
required: Crate[Fruit] 
     val fruit:Crate[Fruit] = cra 
           ^

scala> val fruit:Crate[Fruit] = cro 
<console>:10: error: type mismatch; 
found : Crate[Orange] 
required: Crate[Fruit] 
     val fruit:Crate[Fruit] = cro 

scala> p(cra) 
<console>:12: error: type mismatch; 
found : Crate[Apple] 
required: Crate[Fruit] 
     p(cra) 
     ^

scala> p(cro) 
<console>:12: error: type mismatch; 
found : Crate[Orange] 
required: Crate[Fruit] 
     p(cro) 

그러나이 나는이와 방법 페이지를 호출 할 수있는 이유 크레이트가 공분산하지 않을 때? :

scala> p(Crate(new Apple)) 
Crate([email protected]) 

scala> p(Crate(new Orange)) 
Crate([email protected]) 

몇 가지 기본 원칙을 놓쳤습니까? 후자의 경우

답변

6

는, 컴파일러는이 작업 할 실제로 완벽하게 괜찮있는

p(Crate((new Apple): Fruit)) 

을 말한다 있다고 가정합니다. 수동

val f: Fruit = new Apple // totally fine 
p(Crate(f))    // Also totally fine 

했던 것처럼이 컴파일러는 당신이 그것을 모두 밖으로 입력하지 않고 당신의 유형과 의미를 파악하려고 적용되는 엄청난 마법의 단지 작은 부분 동일합니다.

+0

감사합니다. 컴파일러가 메소드 p에 대한 크레이트의 불변성을 단락시키는 것처럼 보입니다. 개발자가 작업하기를 원한다고 가정 할 때입니다. 나는 crate가 cro, cra와 함께 작동하는 prate 방법으로 Crate [+ T]로 정의되어야한다고 생각했습니다. – ssanj

+1

@ssanj - 당신이 맞습니다. 이미'cro'와'cra'와 함께 작업하려면'+ T'로 정의되어야합니다. 그러나 유형을 지정하지 않고 새로운 것을 생성 할 때는 합리적인 것이 있으면 합리적인 것을 원한다고 가정합니다. –