【问题标题】:Why this type of implicit conversion is illegal?为什么这种类型的隐式转换是非法的?
【发布时间】:2012-01-30 07:50:03
【问题描述】:

我在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
  }

编译成功。谁能告诉我这两者有什么区别?

【问题讨论】:

  • 不知道确切的答案,但我想Predef中有一个隐式转换字符串-> int。因此,添加该类型的新转换会使事情变得模棱两可。

标签: scala implicit-conversion


【解决方案1】:

好,我们从头说起,为什么第一种情况会失败:

  1. 您尝试定义一个将String 转换为Int 的隐式方法,并为此调用toInt
  2. 很遗憾,toInt 不是String 类的一部分。因此,编译器需要找到一个隐式来将str 转换为具有toInt:Int 方法的东西。
  3. 还好Predef.augmentStringString转换成StringOps,就有这样的方法。
  4. 但是Int类型也有这样一个方法,并且你定义了一个返回类型,方法strToInt2可以递归调用,并且由于方法是隐式的,它可以用于转换带有@987654333的东西@函数。
  5. 编译器不知道要使用哪个隐式方法(在您的和 Predef.augmentString 之间,并引发错误。

在第二种情况下,由于省略了返回类型,strToInt2 函数不能递归,并且不再有两个候选者来转换String

但是,如果在此定义之后,您尝试:"2".toInt,错误又回来了:当您拥有 String 时,您现在有两种方法可以使用 toInt:Intfunction 获取某些东西。

【讨论】:

  • 那么......我们如何解决这个问题?我需要一个stringToInt 方法。我可以这样定义它:def string2Int(string: String): Int = Predef.augmentString(string).toInt 来解决歧义,但不幸的是,这会破坏同一范围内的显式"2".toInt(它不再编译)。有什么方法可以在同一范围内同时获得隐式 String -> Int 转换和显式 string.toInt
猜你喜欢
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
相关资源
最近更新 更多