在scala 2.8中从String到Int的隐式转换

时间:2009-11-12 23:33:47

标签: scala scala-2.8

以下片段是否有问题: -

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警告
... \斯卡拉-2.8测试的\ src \ Imp.scala
    错误:错误:第(4)行错误:类型不匹配;
发现:字符串
要求:?{val toInt:?}
请注意,隐式转换不适用,因为它们不明确:
对象Imp中的方法string2Int类型(s:String)Int
对象Predef中的方法augmentString类型为(x:String)scala.collection.immutable.StringOps
可能的转换函数从String到?{val toInt:?} 隐式def string2Int(s:String):Int = s.toInt

3 个答案:

答案 0 :(得分:23)

发生的事情是Java没有在toInt上定义String方法。在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")
  }
}

答案 1 :(得分:8)

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

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

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

答案 2 :(得分: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)
  }
}

我仍然感到困惑的是,为什么两个implicits进入范围并且在我提供隐式时发生冲突,以及当我没有为String提供一个时,Predef为什么没有进入范围。我想有关从String到Int的隐式转换的问题仍然存在。