TraversableOnce方法的签名如下:
def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus)
我可以用它:
scala> (1 to 10).sum res0: Int = 55
在这种情况下,编译器正在注入Numeric [B]本身,因此在范围内必须有一个明确的隐含值.如果我使用Predef.implicitly自己注入,则会发生这种情况:
scala> (1 to 10).sum(implicitly) <console>:6: error: ambiguous implicit values: both method conforms in object Predef of type [A]<:<[A,A] and method stringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] match expected type T (1 to 10).sum(implicitly) ^
为什么这个含糊不清?
我可以使歧义消失
scala> (1 to 10).sum(implicitly[Numeric[Int]]) res2: Int = 55
要么
scala> (1 to 10).sum[Int](implicitly) res3: Int = 55
我认为这与事实一样,事实上,sum声明一个新的类型参数B>:A(显然是,见下面的编辑),但我仍然困惑为什么在第一个例子中明确地找到了一些东西但不是第二个
scala> class As[A](as : A*) { | def sum(implicit num : Numeric[A]) : A = as.foldLeft(num.zero)(num.plus) | } defined class As scala> (new As(1,2,3,4)).sum res0: Int = 10 scala> (new As(1,4)).sum(implicitly) res1: Int = 10
所以,你可以看到隐含的任何调用不是模糊的
解决方法
简短的答案:由于B>:无法推断隐含调用的结果类型.
更长的答案.当定义为隐式的参数缺失时,编译器将搜索当前作用域的任何类型为Numeric [B>:Int]的隐式值,并将使用最具体的 – Numeric [Int].
但是,如果您隐式指定参数(隐式[T](隐含e:T)的调用):T)首先必须解析类型参数T.而scala运行时显然没有这样做.
这跟调用一样:
scala> var f = implicitly <console>:5: error: ambiguous implicit values: both method conforms in object Predef of type [A]<:<[A,A] and method stringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,String] match expected type T var f = implicitly ^
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。