1

私は次のコードを持っています:

trait DBO
trait BSONWriter[S]

trait HasWriter {
   implicit def writer[T <: BSONWriter[_ <: DBO]]: T
}

そして、すべてが大丈夫でした!それを my に混ぜる場合を除いて、すべてのコレクションobjectsのメソッドと、これらすべてのオブジェクトとそれらのコンパニオン クラスmapで暗黙的に使用するその他のものは、次のようなメッセージでエラーを表示するようになりました。CanBuildFrom

  • あいまいな暗黙の値: タイプ [T <: reactmongo.bson.handlers.BSONWriter[_ <: traits.DBO]]=> T の trait Saving のメソッド ライターと、タイプ [A]=> scala のオブジェクト Buffer のメソッド canBuildFrom の両方。 collection.generic.CanBuildFrom[scala.collection.mutable.Buffer.Coll,A,scala.collection.mutable.Buffer[A]] 予想される型と一致します scala.collection.generic.CanBuildFrom[scala.collection.mutable.Buffer[models. world.Star],traits.IsInWorld with org.bundlelib.traits.Groupable{def asBSON: reactmongo.bson.AppendableBSONDocument},That]

今、私は理解していません、それはなぜですか?混乱した暗黙的なメソッドのシグネチャは異なります! どうすればこれを防ぐことができますか?

4

1 に答える 1

7

短い例が問題を示していると思います:

trait Foo

trait Implicits {
    implicit def b[T <: String]: T

    implicit def run = implicitly[Foo]
}

これは正しくコンパイルされます。では、何が起こっているのでしょうか? で実行-Xprint:typer:

implicit def run: foo.Foo = scala.this.Predef.implicitly[foo.Foo](Implicits.this.b[Nothing])

問題は、Nothing(およびコンパイラーが知る限り、他の型) が両方ともFooであるということ<: Stringです。の型bはあまりにも多態的であるため、基本的にはあなたが求めているあらゆる暗黙のものと一致します。これがあなたの例で起こっていることです: Nothingis both T <: BSONWriter[_ <: DBO]and CanBuildFrom[...].

あなたへの私の提案は、非常にポリモーフィックな暗黙のメソッドを作成しないことだと思います。writerあなたの例では、あなたが本当にポリモーフィックになりたいのかどうか、私は実際に疑問に思っています。多分これはあなたが望むものですか?

trait HasWriter[T <: BSONWriter[_ <: DBO]] {
   implicit def writer: T
}

それは暗黙の問題を回避します。

于 2013-01-13T16:40:08.997 に答える