Scala - 一种不可靠的隐式方法正在弄乱整个CanBuildFrom事物

non*_*com 1 types scala implicit

我有以下代码:

trait DBO
trait BSONWriter[S]

trait HasWriter {
   implicit def writer[T <: BSONWriter[_ <: DBO]]: T
}
Run Code Online (Sandbox Code Playgroud)

一切都很好!除了当我把它混合到我的时候objects,map所有集合的方法以及隐含CanBuildFrom在所有这些对象及其伴随类中使用的其他东西现在显示错误消息,如:

  • 模糊隐含值:特征中的方法编写器保存类型[T <:reactivemongo.bson.handlers.BSONWriter [_ <traits.DBO]] => T和方法canBuildFrom在类型为[A] => scala的对象缓冲区中. 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]

现在我不明白,为什么?混淆隐式方法的签名是不同的!我该如何防止这种情况?

Owe*_*wen 7

我想一个简短的例子将显示问题:

trait Foo

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

    implicit def run = implicitly[Foo]
}
Run Code Online (Sandbox Code Playgroud)

这个编译正确 - 所以发生了什么?运行-Xprint:typer:

implicit def run: foo.Foo = scala.this.Predef.implicitly[foo.Foo](Implicits.this.b[Nothing])
Run Code Online (Sandbox Code Playgroud)

问题是Nothing(和其他类型,就编译器所知),都是Foo<: String.类型b太多态,所以它基本上匹配你所追求的任何隐含.这是你的例子中发生的事情:NothingT <: BSONWriter[_ <: DBO]CanBuildFrom[...].

我想我给你的建议是不要制作那么多态的隐式方法.在你的例子中,我实际上想知道你是否真的想要writer像它一样多态.也许这就是你想要的?

trait HasWriter[T <: BSONWriter[_ <: DBO]] {
   implicit def writer: T
}
Run Code Online (Sandbox Code Playgroud)

这将避免隐含的问题.