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

时间:2013-01-13 16:19:38

标签: scala types implicit

我有以下代码:

trait DBO
trait BSONWriter[S]

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

一切都很好!除非我将其混合到我的objects中,所有集合中的map方法以及在所有这些对象及其伴随类中隐式使用CanBuildFrom的其他内容现在都会显示错误消息:

  
      
  • 模糊隐含值:特征中的方法编写者保存类型[T&lt;:reactivemongo.bson.handlers.BSONWriter [_&lt ;: traits.DBO]] =&gt;   T和方法canBuildFrom对象Buffer类型[A] =&gt;   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   使用org.bundlelib.traits.Groupable {def asBSON:   reactivemongo.bson.AppendableBSONDocument},即]
  •   

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

1 个答案:

答案 0 :(得分: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<: Stringb的类型过于多态,因此它基本匹配任何隐含的内容。这就是您的示例中发生的情况:Nothing同时是T <: BSONWriter[_ <: DBO]CanBuildFrom[...]

我想我给你的建议是不要制作具有多态性的隐式方法。在您的示例中,我实际上想知道您是否真的希望writer具有多态性。也许这就是你想要的?

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

这将避免隐含的问题。