【问题标题】:View bounds and ambiguous implicit conversion error查看边界和模棱两可的隐式转换错误
【发布时间】:2012-07-30 06:58:38
【问题描述】:

这是我之前的帖子ambiguous implicit conversion errors的一个更简单的版本

这是来自How can I chain implicits in Scala?帖子的代码sn-p

class A(val n: Int)
class B(val m: Int, val n: Int)
class C(val m: Int, val n: Int, val o: Int) {
  def total = m + n + o
}

object T2 {
  implicit def toA(n: Int): A = new A(n)
  implicit def aToB[A1 <% A](a: A1): B = new B(a.n, a.n)
  implicit def bToC[B1 <% B](b: B1): C = new C(b.m, b.n, b.m + b.n)

  // works
  println(5.total)
  println(new A(5).total)
  println(new B(5, 5).total)
  println(new C(5, 5, 10).total)
}

现在,如果我添加一个类 D 和隐式 def dToC,如下所示,我会在 sn-p 中显示的位置出现错误。

class A(val n: Int)
class B(val m: Int, val n: Int)
class D(val m: Int, val n: Int) //Added by me
class C(val m: Int, val n: Int, val o: Int) {
    def total = m + n + o
}

object T2 {
  implicit def toA(n: Int): A = new A(n)
  implicit def aToB[A1 <% A](a: A1): B = new B(a.n, a.n)
  implicit def bToC[B1 <% B](b: B1): C = new C(b.m, b.n, b.m + b.n)
  implicit def dToC[D1 <% D](d: D1): C = new C(d.m, d.n, d.m + d.n)  //Added by me

  println(5.total) //Ambiguous implicit conversion error
  println(new A(5).total) //Ambiguous implicit conversion error
  println(new B(5, 5).total) //Ambiguous implicit conversion error
  println(new C(5, 5, 10).total) 
}

我不明白bToCdToC 如何成为println(new B(5, 5).total) 的可能转换函数。

【问题讨论】:

  • 您可以通过删除class Adef toAdef aToB 来进一步简化它,歧义仍然存在(但我也不明白,为什么)。
  • 如果第二个参数列表包含函数,则在搜索隐式时似乎未解析第二个参数列表。在第二个参数列表中使用“正常”隐式参数,代码可以正常工作。如果这是错误或功能,我找不到任何提示。
  • @mhs 是的,删除 class A 作为独立帖子是有意义的。但我保留了class A,以便人们可以与How can I chain implicits in Scala? 帖子中的精彩解释相关联。
  • 我猜这个问题是由你的类型限制或更好的上下文限制引起的。错误消息显示: ... [B1](b: B1)(implicit evidence$2: B1 => B)C 对象 $iw 中的方法 bToC 和 [D1](d) 类型的对象 $iw 中的方法 dToC : D1)(implicit evidence$1: D1 => D)C ... 方法的类型不是 B 和 D 而是 B1 和 D1。这些是上下文边界,不再是视图边界。这就是证据告诉我们的。不幸的是,我不知道如何解决这个问题。

标签: scala implicit-conversion


【解决方案1】:

视图边界显然被转换为一个额外的隐式函数参数。所以bToCdToC 都被翻译成[T](x: T)(implicit f: T =&gt; Something): C

问题在于编译器在歧义检查中忽略了隐含参数的存在/不存在。

case class Foo[A](value: A)
implicit def foo[A](x: A)(implicit ev: Any =:= String) = Foo(x)
implicit def bar[A](x: A)(implicit ev: Any =:= Int) = Foo(x)
1.value //Ambiguous though none are applicable

【讨论】:

  • 谢谢!但这是一个功能还是一个错误?顺便说一句,=:= 是什么@
  • 出于某种原因,我相信这是设计使然,但我在规范中找不到它,所以我不确定。 A =:= B 类型的值证明 ABmore details here。对于此示例,请随意将其替换为任何其他类型,无论值是否存在,代码都不会编译。
【解决方案2】:

(1) 整数=>A=>B=>C

(2) 整数=>A=>D=>C

可以选择2条路径,编译器不知道该走哪条路径,所以才会出现模糊隐式转换错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多