Scala types: Class A is not equal to the T where T is: type T = A

前端 未结 3 707
一生所求
一生所求 2021-01-19 05:13

I was reading the section 20.7 of the book Programming in Scala and I was wondering why while this code compiles:

class Food
class Fish extends Food
class Gr         


        
相关标签:
3条回答
  • 2021-01-19 05:48

    I believe bessy eat (new bessy.SuitableFood) compiling is a bug (which was fixed in 2.11). Because another subtype of Animal could have a SuitableFood for which new makes no sense, e.g. type SuitableFood = Food or even type SuitableFood = Food with Int (Food with Int is a perfectly nice subtype of Food!).

    0 讨论(0)
  • 2021-01-19 05:52

    It's because bessie is declared Animal rather than Cow. bessie.SuitableFood is a "path-dependent type" (see below).

    Try this:

    val clarabelle: Cow = new Cow
    
    clarabelle eat (new Grass)
    

    This works because the compiler can deduce that clarabelle.SuitableFood = Grass from clarabelle's declared type.

    Since bessie is declared Animal, not Cow, the compiler can't safely deduce that bessie.SuitableFood = Grass.* When you say new bessie.SuitableFood, the compiler generates code to look at the actual bessie object and generate a new instance of the appropriate type. bessie.SuitableFood is a "path-dependent type": the "path" (the bessie. part) that leads to the last identifier (SuitableFood) is actually part of the type. This enables you to have a custom version of a type for each individual object of the same class.


    *Well, actually, I think that if the compiler were a little smarter, it could deduce that bessie.SuitableFood = Grass, since bessie is a val, not a var, and therefore won't change its type. In other words, the compiler ought to know that even though bessie is declared Animal, she's really a Cow. Perhaps a future version of the compiler will make use of this knowledge, and perhaps there's a good reason why that wouldn't be a good idea, which someone more expert than I will tell us. (Postscript: One just did! See Travis Brown's comment below.)

    0 讨论(0)
  • 2021-01-19 05:56

    Regarding the second part of your question: it doesn't. Animal doesn't specify that its food is Food, but some subtype of Food. Would the compiler accept this, code like your example would compile, and wrongly so. The compiler doesn't know that the necessary subtype is Grass (which is why eat(new Grass) doesn't work either), it just knows that there are some foods your cow can't eat and is cautious about it.

    0 讨论(0)
提交回复
热议问题