1

问题不是关于AnyRef.clone(),而是关于具有相似语义的案例。

我想为可能创建自身副本的类定义一个接口:

trait Cloneable {
  def clone() : this.type
}

class Test(val store : Int) extends Cloneable {
  def clone() = new Test(store)
}

路径依赖this.type不起作用,因为this.typeTest类型和扩展Test. 然后后代应该覆盖克隆方法以匹配它自己的类型。

我应该如何定义 Cloneable 特征的类型要求?

我查看了 scala 集合并在这里找到了提示:定义TestLiketrait,处理类型限制,以及Test体现相应 trait 的类。

如果可能的话,我想避免不必要的笨拙


按照建议尝试自我重复模式:

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尽管SubStoreCloneablevia 的后代Store。但是带有类型参数的StorefinalizeCloneable接口Store及其所有后代都缺乏适当的clone()方法限制

4

1 回答 1

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[MyClass2] cloneObject(new MyClass2(3,4))

因为你有一个 Cloner[MyClass1] 但没有一个 Cloner[MyClass2] 在范围内。

虽然cloneObject(new MyClass1(3))会编译。

于 2013-08-21T10:08:05.257 回答