【发布时间】:2023-03-24 23:37:01
【问题描述】:
sum方法在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 的事实有关(显然是,见下文编辑),但我仍然对为什么会这样感到困惑可以在第一个示例中明确找到,但在第二个示例中找不到?
编辑 - 解决 subsub 的愚蠢评论(下)
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, 2, 3, 4)).sum(implicitly)
res1: Int = 10
所以,你可以看到,任何隐式调用都不是模棱两可的
【问题讨论】:
-
它与任何隐式调用一样模棱两可。
scala> Predef.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 Predef.implicitly。因此,潜在的含义可能类似于“在这里找不到任何合适的隐含事物,请帮助!” -
@subsub - 查看我的编辑。这正是正在发生的事情。我在问为什么隐式调用被推断为导致模棱两可的隐式。如果cope中有匹配的隐式值,为什么无参数调用有类似的问题?
-
如果我的评论很空洞,你为什么要编辑你的问题?好吧,这是另一个:
class Bs[A](bs : TraversableOnce[A]) { def sum(implicit num : Numeric[A]) : A = bs.foldLeft(num.zero)(num.plus) }; (new Bs(1 to 10)).sum(implicitly) -
向你证明这是多么愚蠢。我问为什么在特定情况中对
implicitly的调用是模棱两可的。你回答:“嗯,这里很模糊”对于一个完全不同的情况! -
有趣的是,接受的答案包括那种完全不同的空洞情况;-)