2016-06-10 11 views
0

여기에 스칼라 n00b가 있습니다. 확실히 나는 PDT를 이해하지만 확실하게하고 문제를 쳤다. 여기에 내가 여기에 재현 할 수 있습니다 샘플 코드와 이전 문제는 Scala types: Class A is not equal to the T where T is: type T = A입니다 :경로 종속 형식 예제가 작동하지 않습니다.

1: class Food 
2: class Fish extends Food 
3: class Grass extends Food 
4: 
5: abstract class Animal { 
    6: type SuitableFood <: Food 
    7: def eat(food: SuitableFood) 
8: } 
9: 
10: class Cow extends Animal { 
    11: type SuitableFood = Grass 
    12: override def eat(food: Grass) {} 
13: } 
14: 
15: val bessy: Animal = new Cow // [1] 
16: 
17: bessy eat (new bessy.SuitableFood) // [2] 

원래 포스터는 내가 그것을해야 생각이 컴파일했다,하지만하지 않습니다. 내가 스칼라 REPL에 붙여 넣을 경우 성공적 베시 생성 [1] :

scala> val bessy: Animal = new Cow 
bessy: Animal = [email protected] 

하지만, [2], 나에게 내가 이해하지 못하는 오류 제공 :

scala> bessy.eat(bessy.SuitableFood) 
<console>:17: error: value SuitableFood is not a member of Animal 
     bessy.eat(bessy.SuitableFood) 
        ^

을 내가 붙여 경우를 파일로 'scalac'그것, 나는 얻는다. 왜? bessy은 암소 개체로 type SuitableFood = Grass이 정의되어 있고 bessy.SuitableFood은 클래스 유형입니다 (그렇지 않습니까?). 무엇이 잘못 되었나요?

답변

2
  1. 당신은 (new bessy.SuitableFood)에서 new 누락되었습니다.

  2. 당신이이 문제를 해결 한 후, bessybessy.SuitableFood을 모르는 컴파일러 있도록 입력 Animal하지 Cow이 정의됩니다 Grass이다 : 그것은 단지 추상적 인 유형, 그래서 new bessy.SuitableFood는 (같은 new A 아무튼 작동하지 않습니다 'A이 유형 매개 변수 일 때). 예 : 일부 다른 하위 유형 Animaltype SuitableFood = Food을 선언하고 new Food을 선언 할 수 있다고 생각하십시오. 2.10.6에서 확인했지만 컴파일 된 버그라고 생각합니다.

는 그러므로 나는 .SuitableFood 가상 유형의 종류 것이기 때문에 적절한 음식을 반환합니다 "새로운 bessy.SuitableFood을"생각 그럼 '암소'때 'SuitableFood은'잔디 '가 될 것입니다. PDT가 그렇게하지 않으면 PDT의 가치를 알 수 없습니다.

여기 PDT와 관련해의 요점은 당신이 경우bessy.SuitableFoodbessy 그것을 먹을 수있다이다; 그녀는 spot.SuitableFood을 먹을 수 없습니다 (컴파일러가 일 경우 정적으로을 알 수 있습니다). 하지만이 예제에서는 bessy.SuitableFood을 생성 할 방법이 없습니다. 이유는 없으므로 (컴파일러에게 알릴 방법이 없습니다) type SuitableFood은 public 매개 변수가없는 생성자가있는 클래스입니다. 당신은 Animal에 메서드를 추가하여 문제를 해결할 수 있습니다

abstract class Animal { 
    type SuitableFood <: Food 
    def eat(food: SuitableFood) 
    def newSuitableFood(): SuitableFood 
} 

class Cow extends Animal { 
    ... 
    def newSuitableFood() = new Grass 
} 

지금 bessy.eat(bessy.newSuitableFood) 컴파일하고 작동합니다.

+0

나는 포인트 # 1을 얻지 못했고, 나의 코드 사본에 바로 '새로운'것이있다. 어떤 라인에 결함이 있는지 나타낼 수 있습니까? 원본에 줄 번호를 추가했습니다. 다시 한 번 강조하자면, "이 문제를 해결 한 후에 bessy는 Cow가 아닌 ​​Animal 타입을 갖도록 정의되어 있으므로 컴파일러는 bessy를 알지 못합니다. SuitableFood는 Grass입니다!" 따라서 .SuitableFood가 가상 유형의 일종이 될 것이므로 이 'Cow'일 때 "PreferFood"가 'grass'가 될 것이므로 "new bessy.SuitableFood"가 적절한 식품을 반환 할 것이라고 생각했습니다. PDT가 그렇게하지 않으면 PDT의 가치를 알 수 없습니다. – user3779002

+0

"[2], 나는 이해하지 못하는 오류를 준다 :'scala> bessy.eat (bessy.SuitableFood)'".여기에는 '새'가 없습니다. –

+0

"그러므로 나는"new bessy.SuitableFood "가 이기 때문에 적합한 음식을 반환 할 것이라고 생각했다 .SuitableFood는 일종의 가상 유형이 될 것이다."하지만 왜이 유형에는 매개 변수가없는 생성자가 필요하겠습니까? 이 작업을 올바르게 수행하는 방법에 대한 해답을 편집했습니다. –