首页 文章

scala中类似于cloneable的trait的正确类型规范

提问于
浏览
1

问题不在于 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 是通过 StoreCloneable 后代 . 但 Store finalize Cloneable 接口的类型参数 Store 及其所有后代缺少正确的 clone() 方法限制

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的隐含值:Cloner [MyClass2] cloneObject(new MyClass2(3,4))

    因为你有一个Cloner [MyClass1]而不是范围内的Cloner [MyClass2] .

    cloneObject(new MyClass1(3)) 将编译 .

相关问题