gpt4 book ai didi

java - 循环增量 : Which is "better"?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:38:55 28 4
gpt4 key购买 nike

当您有一个表示为数组的循环缓冲区,并且您需要环绕索引(即,当您达到可能的最高索引并递增它时),是否“更好”:

return (++i == buffer.length) ? 0: i;

或者

return ++i % buffer.length;

使用模运算符有什么缺点吗?它比第一个解决方案的可读性差吗?

编辑:

当然应该是++i而不是i++,改了。

编辑 2:

一个有趣的注意事项:我在 Doug Lea 的 ArrayBlockingQueue 实现中找到了第一行代码。

最佳答案

Update: OP has admitted in a comment that it should have been pre-increment instead. Most of the other answers missed this. There lies proof that the increment in this scenario leads to horrible readability: there's a bug, and most people couldn't see it.

最易读的版本如下:

return (i == buffer.length-1) ? 0 : i+1;

使用 ++ 会给检查增加不必要的副作用(更不用说我强烈认为你应该改用预增量)

原代码有什么问题?让我们看看,好吗?

return (i++ == N) ? 0 : i; // OP's original, slightly rewritten

所以我们知道:

  • ipost 递增的,所以当 i == N-1return 语句之前时,这将返回 N 而不是立即返回 0
    • 这是故意的吗?大多数时候,目的是使用 N 作为唯一上限
  • 变量名 i 按照命名约定暗示了一个局部变量,但真的是这样吗?
    • 由于副作用,需要仔细检查它是否是一个字段

相比之下:

return (i == N-1) ? 0 : i+1; // proposed alternative

这里我们知道:

  • i 不被修改,不管是局部变量还是字段
  • i == N-1时,返回值为0,比较典型的场景

% 方法

或者,您也可以使用 % 版本,如下所示:

return (i+1) % N;

% 有什么问题?好吧,问题是即使大多数人认为它是 modulo 运算符,但它不是!它是余数 运算符 ( JLS 15.17.3 )。很多人经常把这个弄糊涂。这是一个经典的例子:

boolean isOdd(int n) {
return (n % 2) == 1; // does this work???
}

那个密码坏了!!!它为所有负值返回 false!问题是 -1 % 2 == -1,尽管在​​数学上 -1 = 1 (mod 2)

% 可能很棘手,这就是为什么我推荐使用三元运算符版本。不过,最重要的部分是消除增量的副作用。

另见

关于java - 循环增量 : Which is "better"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2801581/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com