私は何日も暗黙の変換の問題に取り組んできましたが、どういうわけか私は自分が間違っていることを理解できません。暗黙の問題を扱うSOに関する他のすべての質問を読みましたが、問題が何であるかはまだわかりません。
例として、次のようなJavaインターフェースを考えてみましょう(簡潔にするためにTはObjectを拡張します)。
public interface JPersistable<T extends Object> {
public T persist(T entity);
}
Scalaでは、次のことを行います。
case class A()
case class B() extends A
case class C()
case class D() extends C
trait Persistable[DTOType <: A, EntityType <: C] {
// this would be implemented somewhere else
private def doPersist(source: EntityType): EntityType = source
// this does not implement the method from the Java interface
private def realPersist(source: DTOType)(implicit view: DTOType => EntityType): EntityType = doPersist(source)
// this DOES implement the method from the Java interface, however it throws:
// error: No implicit view available from DTOType => EntityType.
def persist(source: DTOType): EntityType = realPersist(source)
}
case class Persister() extends Persistable[B, D] with JPersistable[B]
object Mappings {
implicit def BToD(source: B): D = D()
}
object Test {
def main(args: Array[String]) {
import Mappings._
val persisted = Persister().persist(B())
}
}
コメントで述べたように、コンパイル時に例外が発生します。私の質問は次のとおりです。
1)明示的に暗黙の変換を指定する必要があるのはなぜdoRealPersist
ですか?次のことを行っても、変換が行われることを期待していました。
trait Persistable[DTOType <: A, EntityType <: C] {
// this would be implemented somewhere else
private def doPersist(source: EntityType): EntityType = source
def persist(source: DTOType): EntityType = doPersist(source)
}
ただし、これもコンパイルされません。
persist
2)実際のメソッド呼び出し()ではなく、コンパイルが失敗するのはなぜval persisted = Persister().persist(B())
ですか?これは、EntityTypeとDTOTypeの実際のタイプがわかっている最初の場所ですよね?
3)私が達成しようとしていることを行うためのより良い方法はありますか?繰り返しますが、これは私がやろうとしている実際のことではありませんが、十分に近いものです。
この質問が無知である場合は事前にお詫び申し上げます。ご協力いただきありがとうございます。