为什么这种隐式转换是非法的?

时间:2012-01-30 07:50:03

标签: scala implicit-conversion

我在scala中编写了以下隐式转换:

  implicit def strToInt2(str: String):Int = {
    str.toInt
  }

但它引发了这个编译错误:

<console>:9: error: type mismatch;
 found   : str.type (with underlying type String)
 required: ?{val toInt: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method augmentString in object Predef of type (x: String)scala.collection.
immutable.StringOps
 and method toi in object $iw of type (str: String)Int
 are possible conversion functions from str.type to ?{val toInt: ?}
           str.toInt
           ^

如果我删除了返回类型,只需声明它:

  implicit def strToInt2(str: String) = {
    str.toInt
  }

它成功编译。谁能告诉我两者之间的区别是什么?

1 个答案:

答案 0 :(得分:17)

好的,让我们从头开始,为什么在第一种情况下失败:

  1. 您尝试定义将String转换为Int的隐式方法,然后调用toInt
  2. 不幸的是,toInt不是String类的一部分。因此,编译器需要在具有str方法的内容中找到隐式转换toInt:Int
  3. 幸运的是,Predef.augmentStringString转换为具有此类方法的StringOps
  4. 但是Int类型也有这样的方法,并且AS定义了一个返回类型,方法strToInt2可以递归调用,并且由于该方法是隐式的,它可以应用于转换某些东西toInt:Int功能。
  5. 编译器不知道使用哪种隐式方法(在您和Predef.augmentString之间)并抛出错误。
  6. 在第二种情况下,当您省略返回类型时,strToInt2函数无法递归,并且不再有两个候选者可以转换String

    但是,如果在此定义之后,您尝试:"2".toInt,错误就会回来:当您拥有toInt:Int时,您现在有两种方法可以获得具有String功能的内容。< / p>