14

以下片段有什么问题吗:-

object Imp {
  implicit def string2Int(s: String): Int = s.toInt

  def f(i: Int) = i

  def main(args: Array[String]) {
    val n: Int = f("666")
  }
}

我从 2.8 编译器得到以下信息:-

信息:编译完成,出现 1 个错误和 0 个警告
信息:1 个错误
信息:0 个警告
...\scala-2.8-tests\src\Imp.scala
错误:错误:行(4)错误:类型不匹配;
found : String
required: ?{val toInt: ?}
请注意,隐式转换不适用,因为它们不明确:
类型为 (s:String)Int 的对象 Imp 中的
方法 string2Int 和类型为 (x:String) 的对象 Predef 中的方法 augmentString )scala.collection.immutable.StringOps
是从 String 到 ?{val toInt: ?} 的可能转换函数
implicit def string2Int(s: String): Int = s.toInt

4

3 回答 3

24

发生的事情是 Java 没有toIntString. 在 Scala 中,定义该方法的是类StringOps(Scala 2.8) 或RichString(Scala 2.7)。

另一方面,也有一个toInt可用的方法Int(通过另一个隐式,也许?),所以编译器不知道是StringOps通过定义的隐式将字符串转换为,还是Int通过您自己的隐式转换为.

要解决它,请显式调用隐式。

object Imp {
  implicit def string2Int(s: String): Int = augmentString(s).toInt

  def f(i: Int) = i

  def main(args: Array[String]) {
    val n: Int = f("666")
  }
}
于 2009-11-13T11:41:06.740 回答
8

范围内已经存在隐式转换,来自scala.Predef。您无需声明自己的隐式转换即可将toInt方法添加到String. 您有 3 个选项(我会选择最后一个!):

  • 将您的方法名称更改为类似asInt
  • 取消导入转换Predef
  • 不要费心定义自己的,而是使用toInt与 scala 库捆绑在一起的

请注意,如果它是唯一的,scala 只会使用范围内的隐式转换。

于 2009-11-12T23:37:16.857 回答
1

我想我有一个解决方法。

如果我从 String 参数创建 RichString,则使用我提供的隐式方法从 RichString 到 Int 的隐式转换发生(这适用于 2.7.x 和 2.8)。如果我删除我的隐式,我会得到一个类型错误。

object Imp {

  implicit def string2Int(rs: RichString): Int = rs.toInt

  def f(i: Int) = i

  def main(args: Array[String]) {
    val n: Int = f(new RichString("666"))

    println(n)
  }
}

我仍然很困惑为什么当我提供一个隐式时两个隐式都进入范围并发生冲突,以及当我没有为 Int 提供一个 String 时为什么 Predef 没有进入范围。我想关于从 String 到 Int 的隐式转换的问题仍然悬而未决。

于 2009-11-13T22:55:41.327 回答