【发布时间】:2014-01-10 07:40:31
【问题描述】:
既然我能做到:
case class A(a: Int)
trait C
val x = new A(10) with C
为什么我不能这样做:
type X = A with C
val x = new X(10)
?如果连实例都不能构造,type X = A with C的用例是什么?
【问题讨论】:
既然我能做到:
case class A(a: Int)
trait C
val x = new A(10) with C
为什么我不能这样做:
type X = A with C
val x = new X(10)
?如果连实例都不能构造,type X = A with C的用例是什么?
【问题讨论】:
你得到的错误信息应该给你一个提示:
error: class type required but A with C found
new X(10)
^
X,作为类型别名,被重写为A with C 类型表达式,它不是类类型。后者,根据Scala Language Specification,是:
类型指示符 (§ 3.2.3 ) 指一个类或特征
(强调我的)
换句话说,它不是每个类型表达式。
这不是一个权威的答案,但我不相信可以将类型别名定义为使其成为类类型。一方面,new 表达式理论上 接受 AnnotType,如第 5.1.1 节中所定义。但是,我看不出如何使用第 4.3 节中的类型别名语法来指定您使用的构造函数等。
tl;dr - 除非您的类型别名可直接重写为类类型(例如,您的示例中的 A),否则您不能将其用作类类型,包括使用它调用 new .如果你想这样,你需要一个类声明,即class X(a: Int) extends A(a) with C。
关于你的第二个问题,你说你不能实例化X。啊,但这就是你错的地方!让我根据您的代码向您展示一个示例:
def blah(x: X) = x.toString
val x = new A(10) with C
val y = new A(10)
blah(x) //String = A(10)
blah(y) //type error
因此,当您需要类型约束时,它很有用,因为“别名”类型将与类型别名匹配,即使它没有明确声明为这样。
【讨论】: