为什么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
?
答案 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]
您无法在选项[双]上应用修剪。这就是为什么第一种方法有效,因为你在字符串上应用了修剪。