简体   繁体   English

当标量在Map [K,V]和Traversable [T]之间选择时,隐式是模棱两可的

[英]Implicit is ambiguous when scalac chooses between Map[K,V] and Traversable[T]

While extending MongoDB serialization library I stumbled upon issue with implicits. 在扩展MongoDB序列化库时,我偶然发现了隐式问题。

In sample project referred below scalac fails to choose between implicits for Map[K,V] and Traversable[T] . 在下面提到的示例项目中,scalac无法在Map[K,V]Traversable[T]隐式之间进行选择。 The warning I get after enabling logging is 启用日志记录后收到的警告是

[info] ambiguous implicit values:
[info]  both method mapSetterStringKey in object BsonWritable of type [V](implicit vw: com.osinka.subset.BsonWritable[V])com.osinka.subset.BsonWritable[Map[String,V]]
[info]  and method seqSetter in object BsonWritable of type [T](implicit w: com.osinka.subset.BsonWritable[T])com.osinka.subset.BsonWritable[Traversable[T]]
[info]  match expected type com.osinka.subset.BsonWritable[scala.collection.immutable.Map[String,List[Double]]]
[info]     val bson = DBO(name -> testMap)()
[info]                         ^

If you uncomment marshallers in object BsonMarshallers it works. 如果取消注释对象BsonMarshallersBsonMarshallers它将起作用。 But it fails when both implicits are specified in com.osinka.subset.BsonWritable . 但是,如果在com.osinka.subset.BsonWritable中指定了两个隐式com.osinka.subset.BsonWritable则失败。

Could you please explain why scalac doesn't choose more specific implicit for Map ? 您能否解释一下scalac为什么不为Map选择更具体的隐式?

https://github.com/cppexpert/subset2-implicit-issue https://github.com/cppexpert/subset2-implicit-issue

If I understand your question, this bit from Programming in Scala, First Edition might explain it. 如果我理解您的问题,那么《 Scala编程第一版》中的这一点可能会解释它。

Non-Ambiguity Rule: An implicit conversion is only inserted if there is no other possible conversion to insert. 非歧义规则:仅当没有其他可能的转换要插入时才插入隐式转换。 If the compiler has two options to fix x + y, say using either convert1(x) + y or convert2(x) + y, then it will report an error and refuse to choose between them. 如果编译器有两个修复x + y的选项,例如使用convert1(x)+ y或convert2(x)+ y,则它将报告错误并拒绝在其中进行选择。 It would be possible to define some kind of "best match" rule that prefers some conversions over others. 可以定义某种“最佳匹配”规则,该规则优先于某些转化。 However, such choices lead to really obscure code. 但是,这样的选择会导致代码晦涩难懂。 Imagine the compiler chooses convert2, but you are new to the file and are only aware of convert1—you could spend a lot of time thinking a different conversion had been applied! 想象一下,编译器选择了convert2,但是您是该文件的新手,并且只知道convert1 —您可能会花费大量时间来考虑已应用了另一种转换!

In cases like this, one option is to remove one of the imported implicits so that the ambiguity is removed. 在这种情况下,一种选择是删除导入的隐式之一,以便消除歧义。 If you prefer convert2, then remove the import of convert1. 如果您更喜欢convert2,则删除import convert1。 Alternatively, you can write your desired conversion explicitly: convert2(x) + y. 或者,您可以显式编写所需的转换:convert2(x)+ y。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM