オーバーライドメソッドで具体的な型を返す簡単な方法はありますか?具体的な実装のインスタンスを作成するのはどうですか?具体的なクラスに実装されたチェーンメソッドを呼び出すので、正しい型も返されます。私は(https://stackoverflow.com/a/14905650に基づいて)解決策を持っていますが、私はこれらのことがより簡単であると感じています。Scalaの型パラメータと継承
多くの類似の質問がありますが、みんなのケースは少し異なりますので、別の例を挙げます(https://github.com/valdanylchuk/saiml/tree/master/src/main/scala/saiml/gaから短縮)。可能であれば、コードブロック全体があなたの提案された変更でコンパイルされているかどうかを確認してください。微妙なカスケード効果があるので、返信してください。私は、 "好奇心をそそるテンプレートのパターン"でこの作業をすることはできませんでした。
import scala.reflect.ClassTag
import scala.util.Random
abstract class Individual(val genome: String) {
type Self
def this() = this("") // please override with a random constructor
def crossover(that: Individual): Self
}
class HelloGenetic(override val genome: String) extends Individual {
type Self = HelloGenetic
def this() = this(Random.alphanumeric.take("Hello, World!".length).mkString)
override def crossover(that: Individual): HelloGenetic = {
val newGenome = this.genome.substring(0, 6) + that.genome.substring(6)
new HelloGenetic(newGenome)
}
}
class Population[A <: Individual {type Self = A} :ClassTag](val size: Int,
tournamentSize: Int, givenIndividuals: Option[Vector[A]] = None) {
val individuals: Vector[A] = givenIndividuals getOrElse
Vector.tabulate(size)(_ => implicitly[ClassTag[A]].runtimeClass.newInstance.asInstanceOf[A])
def tournamentSelect(): A = individuals.head // not really, skipped
def evolve: Population[A] = {
val nextGen = (0 until size).map { _ =>
val parent1: A = tournamentSelect()
val parent2: A = tournamentSelect()
val child: A = parent1.crossover(parent2)
child
}.toVector
new Population(size, tournamentSize, Some(nextGen))
}
}
class Genetic[A <: Individual {type Self = A} :ClassTag](populationSize: Int, tournamentSize: Int) {
def optimize(maxGen: Int, maxMillis: Long): Individual = {
val first = new Population[A](populationSize, tournamentSize)
val optPop = (0 until maxGen).foldLeft(first) { (pop, _) => pop.evolve }
optPop.individuals.head
}
}
ありがとうございました! CRTPのバージョンは少しきれいに見えます。インスタンスを作成するために、私はその関数を渡すことを試みます。 HelloGeneticクラスだけでなく、コンパニオンオブジェクトを実装するライブラリユーザーを必要とせずに動作させることができるかどうかはわかりません。私は、私の内部実装の反映を犠牲にしても、インターフェイスを簡単にしたいと思っています。私は完全なプロジェクトでこれを試し、それが間違いなく資格を与えられているにもかかわらず、これを受け入れられた答えとしてマークする前に、より多くの提案があるかどうかを確認します。 –
はい、CRTPはこのプロジェクトのすべてのケースで完璧に動作します。以前に試してみたところ、私は一貫していなかった。 –