在scala中有多个隐式转换

时间:2017-09-18 09:49:47

标签: scala

我想在scala中有2个隐式的comvertor

  1. 将字符串转换为int
  2. 将int转换为float

    implicit def String2Int(v: String): Int = Integer.parseInt(v)
    
  3. 以上是有效的,但是当我在下面写下

     implicit def String2Float(v: String): Float = v.toFloat
    

    它给出编译错误无法将符号解析为Float

    我们可以在一个文件中没有2个隐式转换器吗?

2 个答案:

答案 0 :(得分:1)

在scala中,toInt, toFloat没有@inline implicit def augmentString(x: String): StringOps = new StringOps(x) 等方法。它们从哪里取出?

Scala具有Predef对象,该对象在每个源中隐式导入(即使您没有导入它)。

Predef有以下方法:

String

因此隐式会将StringOps类型的任何值转换为StringOps

def toInt: Int = java.lang.Integer.parseInt(toString) def toFloat: Float = java.lang.Float.parseFloat(toString) ... 定义方法:

str.toFloat

因此,当您编写String时,编译器实际上会将StringOps转换为implicit def String2Float(v: String): Float = v.toFloat 并调用相应的方法。

确定。你的代码有什么问题?

.toFloat

编译器尝试查找具有StringOps的内容,它会在FloatString2Float中通过Float方法找到它。 (toFloat也有toFloat方法)。

编译器“未添加”方法PredefString)到String,因为它无法决定应用哪种隐式转换以及从StringOps隐式转换为String toFoat已被破坏。

因此implicit def String2Float(v: String): Float = java.lang.Float.parseFloat(v) 不再使用Int方法,这就是您遇到错误的原因(无法将符号解析为Float

(实际上,你应该有2个错误: 请注意隐式转换不适用,因为它们不明确:... AND 值toFloat不是String的成员

解决方案是使用

String

就像你在Float案例中所做的那样。

现在它直接将v.toFloat转换为$h = fopen('yourfile', 'r') ; $match = 'username' ; $output = [] ; if ($h) { while (!feof($h)) { $line = fgets($h); //your current search function, which search each line if ( your_search_function($line, $match) === false) { //array $output will not contain matching lines. $output[] = $line; } } fclose($h); //write back to file or do something else with $output $hw = fopen('yourfile', 'w') ; if( $hw ) { foreach( $output as $line ) { fputs($hw, $line) ; } fclose($hw) ; } } ,无需隐式转换(就像id案例中那样)

P.S。感谢@Dima在我的回答中指出错误。

答案 1 :(得分:0)

您可以将String2Float定义为:

implicit def String2Float(v: String): Float = {
  val i:Int = v
  i.toFloat
}

或将隐式转换器传递为:

implicit def String2Float(v: String)(implicit f: String => Int): Float = {
  v.toFloat
}

或隐式获取转换器实例:

implicit def String2Float(v: String): Float = {
  val f = implicitly[String => Int]
  f(v).toFloat
}

在这种情况下,编译器会成功解决所有问题