1

我有以下代码:

trait DBO
trait BSONWriter[S]

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

一切都很好!除了当我将它混合到我objectsmap.CanBuildFrom

  • 模棱两可的隐含值​​:类型为 [T <: reactivemongo.bson.handlers.BSONWriter[_ <: traits.DBO]]=> T 的 trait Saving 中的方法 writer 和类型为 [A]=> scala 的对象缓冲区中的方法 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: reactivemongo.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(和其他类型,据编译器所知)都是Fooand <: 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 回答