我有一个特点:
trait MyTrait extends (Int => MyTrait)
如何将扩展中的MyTrait
限制为MyTrait
的任何实现?
答案 0 :(得分:8)
在scala中,trait Function1[-T1, +R] extends AnyRef
类型是协变的,在Function1签名中用+ R表示:
MyTrait
这意味着你拥有的是正确的。 (Int => MyTrait)
扩展Function1[Int, MyTrait
(与apply
相同)意味着任何扩展MyTrait的类型都必须实现MyTrait
函数,该函数返回{{1}的任何实例}}
根据您当前的MyTrait
签名,以下内容都是合法的:
class Foo extends MyTrait {
def apply(x: Int): Foo = new Foo
}
class Bar extends MyTrait {
def apply(x: Int): Foo = new Foo
}
class Baz extends MyTrait {
def apply(x: Int): MyTrait = new MyTrait { def apply(y: Int) = new Baz }
}
答案 1 :(得分:4)
正如Dan所写,正常行为是返回MyTrait的任何实例。
如果要将其限制为仅返回当前对象类型的实例,则可以这样做:
trait MyTrait[T <: MyTrait[T]] extends (Int => T)
然后当你实施(从Dan复制)
class Foo extends MyTrait[Foo] {
def apply(x: Int): Foo = new Foo
}
class Bar extends MyTrait[Bar] {
def apply(x: Int): Foo = new Foo //Compile error
}
class Baz extends MyTrait[Baz] {
def apply(x: Int): MyTrait = new MyTrait { def apply(y: Int) = new Baz }
}