我正在摆弄我的一个项目欧拉答案,试着让它更短/更清洁/简洁。
我想出了这个:
Sequences.FibonacciBig() // infinite fib sequence of type BigInteger
.TakeWhile(f => f.ToString().Length < 1000)
.Aggregate(1, (i, _) => i++);
我的测试失败,因为实际是1,这似乎很奇怪。我首先想到的是懒惰的可枚举不被评估或类似的东西。我替换为i + = 1并且它工作,测试通过。然后我用++ i替换它仍然有效。
我很困惑为什么在使用后增量运算符时根本不会对语句进行求值。在最坏的情况下,我预计会出现某种一对一的错误,但不会使聚合函数无效地执行任何操作。
有人可以解释一下吗?
答案 0 :(得分:3)
请看以下代码:
private int value = 0;
public int GetValue()
{
return value++;
}
您是否希望它在第一次调用时返回1
?它没有。它返回value
的当前值,然后递增它。你的lambda表达式也是如此。
.Aggregate(1, (i, _) => i++);
它返回i
的当前值,然后递增它(在那一点没有意义,因为你并没有在其他任何地方保持对它的引用。)
预增量和+=
有效,因为它们在返回之前递增值。
答案 1 :(得分:1)
i++
增加i
作为副作用,但i++
表达式的值将是之前的值 {与i
不同,{1}}会增加,其中值将是增量后++i
的值。
换句话说:
i
将其与:
进行比较var i = 3;
var a = i++;
Console.WriteLine("a = {0}, i = {1}", a, i); // a = 3, i = 4
但无论如何,这并不重要,因为你不应该在你的代码中递增var i = 3;
var a = ++i;
Console.WriteLine("a = {0}, i = {1}", a, i); // a = 4, i = 4
。你可以写:
i
因为.Aggregate(1, (i, _) => i + 1)
是一个参数,所以它只是一个本地变量,您以后不会重复使用。
但实际上,为什么不写i
呢?因为这正是您的.Count() + 1
电话所做的......