我有一种类型,我使用它来进行鸭子化:
type t={
def x:Int
...
}
class t2 {
def x:Int=1
}
def myt:t=new t2 //ducktyping
我想编写一个强制接口类型的特征,但这不起作用:
trait c extends t { //interface DOES NOT COMPILE
def x:Int=1
}
另一方面:如果我写了一个特征t1而不是类型t,那么我就失去了鸭式特征:
trait t1 {
def x:Int
}
type t=t1
trait c extends t1 { // t1 can be used as interface
def x:Int=1
}
def myt:t=new t2 // DOES NOT COMPILE since t1 is expected
那么我如何同时使用ducktyping和接口?
答案 0 :(得分:4)
您只能扩展Scala中的类类实体(即类,特征,Java接口),而不是一般类型(即结构类型,类型参数或成员)。但是,您可以自我输入来完成所有这些操作。这意味着我们可以按如下方式重写您的非编译trait c
,
trait c { self : t =>
def x : Int = 1
}
在c
的正文中,this
的类型现在已知为t
,即已知符合结构类型{ def x : Int }
,它将会只能将c
混合到一个实际符合该结构类型的类中(通过直接实现签名,或者如果是抽象的话,通过重新确定自我类型并将义务传播到最终的具体类),
type t = { def x : Int }
trait c { self : t => }
class t2 extends c { // OK, t2 conforms to t
def x : Int = 1
}
def myt : t = new t2 // OK, as before
class t3 extends c { // Error: t3 doesn't conform to c's self-type
def y : String = "foo"
}