假设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,
类型声明 类型 t [tps]&gt;:L&lt;:U 声明 t 到是一个抽象类型,下限类型为 L ,上限类型为 U 。
所以我声明t
是一个带有下限Bird
的抽象类型。 Chicken
不是Bird
的超类,String
也不是Int
。
我想也许是因为Chicken
是Any
而SuperType
可以存储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]&gt;:L&lt; :U 声明 t 是一个抽象类型......“如果”抽象“这个词不在那里,意义的区别是什么?
答案 0 :(得分:0)
我认为混淆是使用术语“约束”和“约束”。 “&lt ;:”和“&gt;:”语法结构用于指定类型约束,而不是边界。当你说
{ type t >: Bird }
你只是在限制类型“t”,这样那种类型的居民必须与Bird共享一个超类。由于Chicken和Bird都扩展了Animal,因此符合约束条件,而Scala允许赋值。这也是你的“虚假”作业的原因(String和Int都与Bird共享超类Any。你提出的后一个约束
{ type t >: Bird <: Animal }
正确地限制了String和Int的示例,因为在String或Int的类型层次结构中不存在满足作为Bird的超类型的约束的类型,同时也是Animal的子类型。但是,这仍然允许您的初始分配。
编辑:关于SO的其他答案说两者都被称为边界。显示我知道多少。 :)