为什么 post-increment 在 .Aggregate(...) 中失败但 pre-increment 成功?
Why does post-increment fail in .Aggregate(...) but pre-increment succeeds?
我正在摆弄我的项目欧拉答案之一,试图让它变得有点 shorter/cleaner/succinct。
我想到了这个:
Sequences.FibonacciBig() // infinite fib sequence of type BigInteger
.TakeWhile(f => f.ToString().Length < 1000)
.Aggregate(1, (i, _) => i++);
我的测试失败了,因为实际是 1,这看起来很奇怪。我首先想到的是懒惰的枚举没有被评估或类似的东西。我用 i += 1 代替,它起作用了,测试通过了。然后我用 ++i 替换它仍然有效。
我很困惑为什么在使用 post-increment 运算符时似乎根本没有对语句求值。在最坏的情况下,我预计会出现某种差一错误,但聚合函数实际上什么都不做。
谁能解释一下?
看下面的代码:
private int value = 0;
public int GetValue()
{
return value++;
}
您希望它在第一次调用时 return 1
吗?它没有。它 return 是 value
的当前值,然后递增它。您的 lambda 表达式也会发生同样的情况。
.Aggregate(1, (i, _) => i++);
它 return 是 i
的当前值,然后递增它(这在这一点上毫无意义,因为您没有在其他任何地方引用它)。
pre-increment 和 +=
之所以有效,是因为它们在 returning 之前增加了值。
i++
作为副作用增加了 i
,但是 i++
表达式的 value 将是值 before i
递增,与 ++i
不同,后者的值将是 i
after 的值。
换句话说:
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
呢?因为这正是您的 Aggregate
调用所做的...
我正在摆弄我的项目欧拉答案之一,试图让它变得有点 shorter/cleaner/succinct。
我想到了这个:
Sequences.FibonacciBig() // infinite fib sequence of type BigInteger
.TakeWhile(f => f.ToString().Length < 1000)
.Aggregate(1, (i, _) => i++);
我的测试失败了,因为实际是 1,这看起来很奇怪。我首先想到的是懒惰的枚举没有被评估或类似的东西。我用 i += 1 代替,它起作用了,测试通过了。然后我用 ++i 替换它仍然有效。
我很困惑为什么在使用 post-increment 运算符时似乎根本没有对语句求值。在最坏的情况下,我预计会出现某种差一错误,但聚合函数实际上什么都不做。
谁能解释一下?
看下面的代码:
private int value = 0;
public int GetValue()
{
return value++;
}
您希望它在第一次调用时 return 1
吗?它没有。它 return 是 value
的当前值,然后递增它。您的 lambda 表达式也会发生同样的情况。
.Aggregate(1, (i, _) => i++);
它 return 是 i
的当前值,然后递增它(这在这一点上毫无意义,因为您没有在其他任何地方引用它)。
pre-increment 和 +=
之所以有效,是因为它们在 returning 之前增加了值。
i++
作为副作用增加了 i
,但是 i++
表达式的 value 将是值 before i
递增,与 ++i
不同,后者的值将是 i
after 的值。
换句话说:
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
呢?因为这正是您的 Aggregate
调用所做的...