以下片段是否有问题: -
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
答案 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
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的隐式转换的问题仍然存在。