我正在学习惰性计算,由下面的代码给出
public static Func<R> Map<T, R>(this Func<T> f, Func<T, R> g)
{
return () => g(f());
}
因为f可能是一个计算量很大的函数来生成T,这就是为什么它被 Package 为Func<T>
,但是Map
返回() => g(f())
,这里f()
更像是一个闭包,必须先准备好,所以在我看来f()
仍然会在() => g(f())
中求值,我知道我的理解是错误的,但是我不知道哪里出了问题,那么编译器是如何启动并使代码仍然是惰性计算的呢(即f()
将不会在() => g(f())
中被调用?
2条答案
按热度按时间gorkyyrv1#
() => g(f())
表示匿名函数,仅此而已。在声明时不会计算该函数中的任何内容。
f()
仅在调用匿名函数时被调用,并且在每次调用匿名函数时被调用。3ks5zfa02#
() => g(f())
是一个lambda expression,它创建了一个匿名函数(实际上是编译器翻译的语法糖-参见@sharplab)。所以在我看来
f()
仍然会在() => g(f())
中求值是,当
() => g(f())
表示的匿名函数将被调用/求值时,即(pseudocde):所以惰性是通过这样一个事实实现的,即计算将不会在
Map
被调用时执行,而是在它的结果被调用时执行,这很容易检查副作用。给出下一个输出:
评估前
内部Map函数
整数为:1