问题描述
我正在阅读《Scala 编程》一书的第 20.7 节,我想知道为什么在编译这段代码时:
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 Grass extends Food
abstract class Animal {
type SuitableFood <: Food
def eat(food: SuitableFood)
}
class Cow extends Animal {
type SuitableFood = Grass
override def eat(food: Grass) {}
}
val bessy: Animal = new Cow
bessy eat (new bessy.SuitableFood)
这段代码没有(其余代码和之前一样,只是最后一行有变化):
This code does not (the rest of the code is the same as before, only the last line changes):
bessy eat (new Grass)
据我所知,Grass 的类型与 Cow.SuitableFood 相同.
And as far as I understand the type of Grass is the same of Cow.SuitableFood.
另外,我还有一个关于这个例子的问题:
Also, I have another question regarding this example:
如果 bessy 是 Animal 类型,编译器怎么知道它需要一个类型适合的食物 -> 草而不是食物类型?因为试图提供一个新的 Food 给我一个类型不匹配的编译错误,但是类 Animal 需要一个类型 Food 并且明确定义了 bessy 的类型:Animal
If bessy is of type Animal, how can the compiler know that it needs a type SuitableFood -> Grass instead of a type Food? 'Cause trying to provide a new Food gives me a compile error of type mismatch, but the class Animal needs a type Food and the type of bessy is explicitly defined: Animal
推荐答案
这是因为 bessie
被声明为 Animal
而不是 Cow
.bessie.SuitableFood
是路径依赖类型"(见下文).
It's because bessie
is declared Animal
rather than Cow
. bessie.SuitableFood
is a "path-dependent type" (see below).
试试这个:
val clarabelle: Cow = new Cow
clarabelle eat (new Grass)
这是可行的,因为编译器可以从clarabelle
的声明类型推导出clarabelle.SuitableFood = Grass
.
This works because the compiler can deduce that clarabelle.SuitableFood = Grass
from clarabelle
's declared type.
由于 bessie
被声明为 Animal
,而不是 Cow
,编译器不能安全地推断出 bessie.SuitableFood = Grass
.* 当您说 new bessie.SuitableFood
时,编译器生成代码以查看实际的 bessie
对象并生成适当类型的新实例.bessie.SuitableFood
是路径依赖类型":path"(bessie.
部分)指向最后一个标识符 (SuitableFood
) 实际上是类型的一部分.这使您可以为同一类的每个单独对象拥有一个自定义版本的类型.
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.
*
*
这篇关于Scala 类型:A 类不等于 T,其中 T 是:type T = A的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!