1

問題は についてAnyRef.clone()ではなく、同様のセマンティックを持つケースについてです。

それ自体のコピーを作成する可能性のあるクラスのインターフェイスを定義したいと思います。

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

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

はクラス タイプと を拡張するクラスで異なるため、パス依存this.typeは機能しません。次に、子孫は clone メソッドをオーバーライドして、独自の型に一致させる必要があります。this.typeTestTest

Cloneable トレイトの型要件をどのように定義すればよいですか?

私は scala コレクションをのぞき見しましたが、ここでヒントを見つけました:TestLike型制限を処理する trait と、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()SubStoreSubStoreCloneableStoreStoreCloneableStoreclone()

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 の暗黙的な値が見つかりませんでした: Cloner[MyClass2] cloneObject(new MyClass2(3,4))

スコープ内に Cloner[MyClass1] がありますが、 Cloner[MyClass2] がないためです。

cloneObject(new MyClass1(3))コンパイルします。

于 2013-08-21T10:08:05.257 に答える