3

假设在 Scala repl 中做了以下声明:

class Animal
class Bird extends Animal
class Chicken extends Bird
type SubType = t forSome { type t <: Bird }
type SuperType = t forSome { type t >: Bird }

正如我所料,SubType是一种符合Bird. 由于Animal是 的超类Bird,因此类型的变量SubType不能保存类型的值Animal

scala> val foo: SubType = new Animal
<console>:10: error: type mismatch;
 found   : Animal
 required: SubType
       val foo: SubType = new Animal

然而这个推论并不像我预期的那样:

scala> val foo: SuperType = new Chicken
foo: SuperType = Chicken@1fea8dbd

分配成功,这些也是如此:

scala> val foo: SuperType = 2
foo: SuperType = 2

scala> val foo: SuperType = "wtf?"
foo: SuperType = wtf?

scala>

同样,这里是SuperType

type SuperType = t forSome { type t >: Bird }

根据SLS 4.3

类型声明 type t [tps ] >: L <: Ut声明为具有下限类型L和上限类型U的抽象类型。

所以我声明t是一个具有下界的抽象类型BirdChicken不是 的超类Bird,既不是String也不是Int

我想这可能是因为 aChicken是一个Any并且 aSuperType可以存储一个Any. 但是,如果我将声明更改为SuperType

type SuperType = t forSome { type t >: Bird <: Animal}

设置什么都没有的上限Animal似乎没有改变。

问题

第一的

我如何分配类型值Chicken Int和存在子句允许String的变量和?SuperType{ type t >: Bird }{ type t >: Bird <: Animal}

第二

引用规范中“抽象”一词的含义是什么,“A类型声明 类型 t [tps]>:L <:U声明t是抽象类型......”如果没有“抽象”这个词吗?

4

1 回答 1

1

我认为混淆是在使用术语“约束”和“约束”之间。"<:" 和 ">:" 语法结构用于指定类型约束,而不是边界。当你说

{ type t >: Bird } 

您只是限制类型“t”,使得该类型的居民必须与 Bird 共享一个超类。由于 Chicken 和 Bird 都扩展了 Animal,因此满足了约束,并且 Scala 允许赋值。这也是您的“虚假”分配起作用的原因(String 和 Int 都与 Bird 共享超类 Any。您提出的后一个约束

{ type t >: Bird <: Animal } 

适当地限制了 String 和 Int 的示例,因为 String 或 Int 的类型层次结构中不存在满足作为 Bird 的超类型同时也是 Animal 的子类型的约束的类型。但是,这仍然允许您进行初始分配。

编辑:关于 SO 的其他答案说两者都称为边界。显示我知道多少。:)

于 2013-04-04T19:50:04.780 回答