【问题标题】:Implicit conversion from String to Int in scala 2.8scala 2.8 中从 String 到 Int 的隐式转换
【发布时间】:2010-12-16 02:50:39
【问题描述】:

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

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) 行错误:类型不匹配;
找到:字符串
必需:?{val toInt: ?}
请注意,隐式转换不适用,因为它们不明确:
类型为 (s: String)Int
的对象 Imp 中的两个方法 string2Int 和 (x:String) 类型的对象 Predef 中的方法 augmentString scala.collection.immutable.StringOps
是从 String 到 ?{val toInt: ?}
的可能转换函数 隐式 def string2Int(s: String): Int = s.toInt

【问题讨论】:

    标签: scala scala-2.8


    【解决方案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 的隐式转换的问题仍然悬而未决。

    【讨论】:

      【解决方案2】:

      发生的情况是 Java 没有在 String 上定义 toInt 方法。在 Scala 中,定义该方法的是 StringOps (Scala 2.8) 或 RichString (Scala 2.7) 类。

      另一方面,Int 上也有一个方法toInt 可用(可能是通过另一个隐式方法?),所以编译器不知道是否要将字符串转换为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")
        }
      }
      

      【讨论】:

      • 感谢您的帮助,我没有意识到 RichString 已被取代。我仍然感到困惑的是,当我不提供隐式时,找不到通过 augmentString 进行的转换,并且会发生类型错误。我试图不使用显式调用,因为要转换的类型是由我尝试编写的实际方法中的类型参数提供的。
      • RichString 没有被取代,它仍然存在。不过,我不知道与 AugmentedString 有什么关系。问题是编译器不知道要调用哪个“.toInt”方法:AugmentedString 上的方法或 Int 上的方法。
      • RichString 还存在吗?我最好把这个删除键签出。
      • @extempore 它仍然存在于 Scala 2.7 中,如图所示。我相当确定。 :-)
      【解决方案3】:

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

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

      请注意,只有在 唯一 的情况下,scala 才会使用范围内的隐式转换。

      【讨论】:

      • 感谢您的快速回复,不幸的是,如果我在上面注释掉我的隐含,Predef 的隐含不会启动,它似乎只有在竞争出现时才在范围内 ;-) toInt选项很好,但我正在探索由类型参数确定的方法中从 String 进行的一系列转换,其中一个是 String,即无操作。
      • 我明天必须用 2.8 试试这个。我一直在生产代码(即使用 2.7)中使用toInt 转换!
      • PredefStringInt 的隐式转换?我知道相反方向的东西(任何+字符串),但不是这个。 Scala 中有没有这样的东西?
      猜你喜欢
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 2015-09-16
      • 1970-01-01
      相关资源
      最近更新 更多