问题不在于 AnyRef.clone()
,而是与具有相似语义的情况有关 .
我想为可能创建自身副本的类定义一个接口:
trait Cloneable {
def clone() : this.type
}
class Test(val store : Int) extends Cloneable {
def clone() = new Test(store)
}
与路径相关的 this.type
不起作用,因为 Test
类与 Test
类类型以及扩展 Test
的类不同 . 然后,后代应该重写克隆方法以匹配其自己的类型 .
我应该如何定义Cloneable特征的类型要求?
我偷看了scala集合,在这里找到了tip:define TestLike
trait,它处理类型限制,类 Test
,它体现了相应的特性 .
如果可能的话,我想避免不必要的笨拙
按照建议尝试自我反复出现的模式:
trait Cloneable[A <: Cloneable[A]] {
def clone() : A
}
class Store[A <: Cloneable[A]](val store : Int) extends Cloneable[A] {
override def clone() : A = new Store[A](store)
}
失败但错误:
Cloneable.scala:6: error: type mismatch;
found : Store[A]
required: A
override def clone() : A = new Store[A](store)
定期模板中的另一个问题:提前完成
class Store(val store : Int) extends Cloneable[Store] {
override def clone() = new Store(store)
}
class SubStore(store : Int, val stash : Double) extends Store(store)
val ss1 = new SubStore(1, 0.5)
val ss2 = ss1.clone()
assert(ss2.isInstanceOf[SubStore])
SubStore
的问题是类型系统忽略了 SubStore
类中缺少 clone()
方法,尽管 SubStore
是通过 Store
的 Cloneable
后代 . 但 Store
finalize Cloneable
接口的类型参数 Store
及其所有后代缺少正确的 clone()
方法限制
1 回答
Scala类型差异允许您以简单的方式实现所需,但您必须远离继承并转到类型类 .
这里的想法是,由于Cloner [A]在类型A中是不变的,因此以下代码将无法编译:
找不到参数cloner的隐含值:Cloner [MyClass2] cloneObject(new MyClass2(3,4))
因为你有一个Cloner [MyClass1]而不是范围内的Cloner [MyClass2] .
而
cloneObject(new MyClass1(3))
将编译 .