了解在Scala中使用map中的方法

时间:2017-11-17 09:16:39

标签: scala

为什么asdf1的行在

中工作
  def trytoDouble(s: String): Option[Double] = {
    try {
      Some(s.toDouble)
    } catch {
      case e: Exception => None
    }
  }

val asdf1 = Source.fromFile("data/my.csv").getLines().map(_.split(",").map(_.trim).map(trytoDouble(_)))

val asdf2 = Source.fromFile("data/my.csv").getLines().map(_.split(",").map(trytoDouble(_.trim)))

虽然asdf2的行给了我错误信息

  

类型不匹配,预期String => NotInferedB,actual:选项[Double]

for trytoDouble

2 个答案:

答案 0 :(得分:1)

您可以简化问题以查明要点:

val oneLine = "line1, 13, 14, 15"               //> oneLine  : String = line1, 13, 14, 15
oneLine.split(",").map(_.trim)                  //> res2: Array[String] = Array(line1, 13, 14, 15)

此行有效

 oneLine.split(",").map(s => trytoDouble(s.trim))//> res3: Array[Option[Double]] = Array(None, Some(13.0), Some(14.0), Some(15.0

但这一行没有:

oneLine.split(",").map(trytoDouble(_.trim))

这是因为编译器不知道如何推断_的类型,关于String和trytoDouble类型的trim扩展。 编译器消息是:

 missing parameter type for expanded function

如果你省略修剪,它就可以了:

  oneLine.split(",").map(trytoDouble(_))          //> res3: Array[Option[Double]] = Array(None, Some(13.0), Some(14.0), Some(15.0

scala中的推理类型系统是有限的。你很快就会遇到这种需要帮助它的情况。

修改

占位符始终在最小的包含表达式中替换。

事实上,

 oneLine.split(",").map(trytoDouble(_.trim))

替换为:

oneLine.split(",").map(trytoDouble(x => x.trim))

但你想要的是:

oneLine.split(",").map( x => trytoDouble(x.trim))

答案 1 :(得分:0)

因为在致电tryToDouble之后它将返回Iterator[Array[Option[Double]]],并且您正在尝试修剪Option[Double]类型的值。 trim不是Option[Double]的成员。 trim期望字符串,但它找到Option [Double]类型值。这就是它抛出错误的原因

Type mismatch, expected String => NotInferedB, actual: Option[Double]

您无法在选项[双]上应用修剪。这就是为什么第一种方法有效,因为你在字符串上应用了修剪。