问题不在于AnyRef.clone()
,而在于具有类似语义的情况。
我想为可能创建自身副本的类定义一个接口:
trait Cloneable {
def clone() : this.type
}
class Test(val store : Int) extends Cloneable {
def clone() = new Test(store)
}
路径相关this.type
不起作用,因为this.type
类类型和扩展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
的问题是类型系统忽略了clone()
类中缺少的SubStore
方法,尽管SubStore
是Cloneable
后代通过Store
}。但是Store
带有类型参数Cloneable
的最终Store
接口及其所有后代缺少正确的clone()
方法限制
答案 0 :(得分:0)
Scala类型差异允许您以简单的方式实现所需,但您必须放弃继承并转到类型类。
trait Cloner[A]{
def cloneObject(input:A):A
}
trait CloningFunctions{
def cloneObject[A](input:A)(implicit cloner:Cloner[A]) = cloner.cloneObject(input)
}
object CloningFunctions extends CloningFunctions
class MyClass1(val b:Int)
class MyClass2(val a:Int,b:Int) extends MyClass1(b)
object Example {
implicit val cloner = new Cloner[MyClass1]{
def cloneObject(input: MyClass1): MyClass1 = new MyClass1(input.b)
}
import CloningFunctions._
cloneObject(new MyClass2(3,4))
}
这里的想法是,由于Cloner [A]在类型A中是不变的,因此以下代码将无法编译:
无法找到参数cloner的隐含值:Cloner [MyClass2] cloneObject(new MyClass2(3,4))
因为你有一个Cloner [MyClass1]而不是范围内的Cloner [MyClass2]。
虽然cloneObject(new MyClass1(3))
会编译。