当评估Option的数据时,我试图使用fold[B](ifEmpty: => B)(f: A => B): B
,但我对结果感到有些困惑:
scala> Some(1).fold(() => "empty")(d => d.toString)
res5: () => String = <function0>
scala> Some(1).fold(() => "empty")(d => d.toString)()
res6: String = 1
此方法的源代码:
@inline final def fold[B](ifEmpty: => B)(f: A => B): B =
if (isEmpty) ifEmpty else f(this.get)
我预计结果为String
,但得到<function0>
,为什么?
==================
我尝试使用以下代码模拟这种情况:
case class Demo(size: Int)
// version 1, with the same fold method as Option
case class X [A <: Demo](data: A) {
def fold[B](ifEmpty: => B)(f: A => B): B = {
if(data.size < 3) ifEmpty else f(data)
}
}
val demo = Demo(2)
val x = X(demo)
x.fold(() => "empty")(d => d.toString) // the result is a function
// version 2
case class X [A <: Demo](data: A) {
def fold[B](g: A => B)(f: A => B): B = {
if(data.size < 3) g(data) else f(data)
}
}
x.fold(g => g.toString)(f => f.toString) // the result is a String
根据演示,似乎结果受到scala类型推断的影响,是吗?
答案 0 :(得分:10)
因为您传递了() => "empty"
作为第一个参数,它是() => String
类型的函数;所以类型B
将是什么。请注意,ifEmpty
参数是按名称调用参数。
如果您不希望B
成为() => String
,而只是String
,请尝试以下方式:
Some(1).fold("empty")(d => d.toString)
编辑后添加了 :版本1和版本2演示之间的主要区别在于版本1中,ifEmpty
是按名称调用参数,在版本2中,g
不是名称调用参数,而是A => B
类型的函数。