【问题标题】:Scala implicit argument's type finding failScala隐式参数的类型查找失败
【发布时间】:2018-03-16 06:56:07
【问题描述】:

试图理解这种隐含发现的案例 - finding implicit of an argument's type。我将官方示例复制粘贴到 IDE 中,只是将方法名称更改为 mul,如下所示:

class A(val n: Int) {
  def mul(other: A) = new A(n + other.n)
}
object A {
  implicit def fromInt(n: Int) = new A(n)
}
1 mul (new A(1))

现在它会导致编译错误:

value mul is not a member of Int

我还尝试使用 String 而不是 Int 进行试验,这再次导致编译错误。

你能解释一下我做错了什么吗?

【问题讨论】:

    标签: scala implicit-conversion implicit


    【解决方案1】:

    def +(other: A) =...def mul(other: A) =... 的区别在于Int 有一个+ 方法,但它没有mul 方法。

    如果方法存在,但不存在所传递的参数类型,则编译器将寻找隐式转换。包含在隐式作用域中的是传递的参数参数的伴随对象。如果找到隐式转换,则评估整个表达式以进行转换。

    如果该方法不存在,则伴随对象中的隐式转换不在隐式范围内。它不会被找到,也不会发生转换。

    如果您要将 implicit def fromInt(... 移到伴随对象之外,则将发生 mul() 转换。

    【讨论】:

    • 哇,非常感谢!这正是问题所在。在应用隐式之前,方法名称应该已经存在于对象上。
    • 很有意思,这种分辨率什么时候有用?
    • @Mikel;这是个好问题。我不知道如何/为什么决定隐式范围规则。得知这件事我有点惊讶。
    • 我尝试使用String作为类型(字段n),并使用方法名称product(而不是mul)。现在它不会再次编译。我们如何解释这一点?如果有类型参数,它就不起作用?
    • 如果您从conversion-from-Int 更改为conversion-from-String,那么方法名称必须是String 类中已经存在的名称,但不是全部方法似乎有效。 split()length() 等方法有效,而 product()drop()head() 等方法无效。我不知道为什么。这可能与 java.String 类的原生方法以及 Scala StringOps 包装器添加的方法有关,但这只是猜测。
    猜你喜欢
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多