1
lcorange 2019-03-03 11:20:04 +08:00
比如你循环体内部用了 i 这个变量,如果有人写了错误的代码,修改了 i 的值,比如写了 i++
这样的话 i 就会在某种异常情况下比 N 大,跳过了 i == N 的情况。循环就停不下来了 但是写 i < N 可以有避免这种情况发生 |
2
lhx2008 OP @lcorange 这种情况下,i < N 就不是超集而是准确定义。
但是我们写 for 循环甚少 N 会变动的情况。那是不是应该不变的时候用 i != N 呢 |
3
lhx2008 OP @lcorange 楼上第二行我看错了。i 会加 2 这种情况,程序已经不能正常运行了,早抛出错误也好吧?
|
4
geelaw 2019-03-03 11:25:26 +08:00 via iPhone 1
我个人更喜欢 i != N,除非内部对 i 有操作。这是 STL 习惯。
|
5
geelaw 2019-03-03 11:27:51 +08:00 via iPhone 2
实际上那里是循环进行条件,而不是循环结束条件。
|
6
lcorange 2019-03-03 11:28:16 +08:00
@lhx2008 不同代码场景不一致的,比如我有个队列的数据要处理 1~100 号用户的,我写成 i<100,即使内部出错,也能保证部分用户正常使用,程序不会崩溃。但是如果我写成!=100,一旦跳过了 100 号,那服务器只能 500 报错了。
当然,你说的也没问题。在比如数值计算之类的场景,错误早就发生出现了。也就谈不上避免更大的 bug 了 |
7
lhx2008 OP @geelaw 是的哈哈,如果看成继续条件写不等于反而是超集。但是我们写代码似乎想的都是终止条件而不是继续条件
|
8
SuperMild 2019-03-03 11:33:55 +08:00 2
i<100 更节省脑力,不用思考 100 会不会被跳过的问题,而且也更符合逻辑,因为 i != N 的意思是不管大于还是小于 N 只要不等于 N 就应该循环,但事实上的逻辑是只有小于 N 才应该循环,等于及大于 N 都不应该循环。
|
9
hundan 2019-03-03 11:35:38 +08:00 via Android
那 i<=N 呢
|
10
SuperMild 2019-03-03 11:37:41 +08:00
另外,现在很多语言都支持 for in, for range 之类的了,有这个功能的最好尽量使用。
|
11
lhx2008 OP @SuperMild for range 我觉得是个不太好的发明,就是前后闭合的指定不清晰,python 取消标准 for 循环我觉得是个败笔。至于输入长度,有 ide 都差不多。
|
12
richard1122 2019-03-03 13:35:35 +08:00
用 < 相对于 != 是担心在循环内部有人又修改了 i 的值? 如楼上说的尽量用 for in 甚至是 arr.forEach 这类循环方式,尽量不用可变的循环变量。
另外同感 for range 不够清晰,kotlin 里面的 0..10 这种也总是记不住到底是多少。。 |
13
Leammin 2019-03-03 14:03:15 +08:00 via Android
《阿里 Java 开发手册》里边也有提到,避免使用等值来作为中断或退出条件,以免条件被"击穿",放在这里应该也是适用的。
|
14
autoxbc 2019-03-03 15:06:20 +08:00 via iPhone
forEach 更加函数式,只要目标有迭代器,就应该避免用 for
|
15
changnet 2019-03-03 15:12:57 +08:00 via Android
尽可能写超集,尤其是这种数字对比,又不增加什么复杂度。比如我们游戏中,策划修改了数值,不写超集程序就容易出问题
如果你的超集很复杂,这个就得看情况了 |
16
akira 2019-03-03 15:30:48 +08:00
就准确指出了终止条件是当 i == n 时,而且 i 肯定是能到 N 的。
----------------- 这个还真不好说,一旦循环体里面的代码没写好, 跳过了 N, 就死循环了 |
17
whileFalse 2019-03-03 15:34:13 +08:00
1. 习惯问题
2. N = -1,step = 2 等条件时,“<”依然适用 3. 目测大部分人都不 care 这些问题,你爱怎么写就怎么写好了 |
18
ipwx 2019-03-03 15:36:31 +08:00
|
19
lhx2008 OP @ipwx 我不知道你如何得出我傲慢,JS 这么多语法糖我不信你记得清楚,比如最简单的 js 里面的 5+种遍历语法和他们的区别。
关于 range,我知道 python 里面是前闭后开,但是到别的语言里面,变成前闭后闭呢?如果我需求是前闭后闭,是不是还用得后面加一这种难看的写法? 这些不清晰,不通用的语法糖,在语言设计的时候本来就应该避免,特别是将其作为关键字的时候。 |
20
hhhsuan 2019-03-03 15:45:11 +08:00 via Android
超集用在这里合适吗
|
21
richard1122 2019-03-03 15:47:43 +08:00
@ipwx
不知道你在说啥,1 .. 10 这种只是 kotlin 提供的众多语言特性之下,库函数提供的一个运算符而已,喜欢用的人把它当作一个语法糖也没问题。 它既不是什么“最基本的功能”,也不是“语言的设计思路”,自己立一个靶子打没意思。 |
22
richard1122 2019-03-03 15:49:59 +08:00
然后才看到楼上提到 python 是左闭右开,而 kotlin 正好相反是左闭又闭的。
同时它提供了左闭右开的另一个函数 until |
23
ipwx 2019-03-03 16:35:52 +08:00
@lhx2008 但是对于 Python 而言,range 是 Python 很早就有的基本写法。而且 Python 就一个语法,range,其他都是用户选择的自己的写法。把 Python 的 range 和其他语言比较,然后说 Python 的 range 不清晰,不通用,这就是傲慢。
因为你在写 Python 不是吗? Python 自己又没有什么一会儿左闭右开,一会儿左开右闭的。所有 Python 的写法,从 range 到 [start: end: step] 这种 slice,都是左闭右开啊。放在一起,它们自己非常融洽,这不就是优雅的语言了吗? - - - - @richard1122 好吧,我反正不会 Kotlin,你说啥就是什么吧。。。 |
24
ThomasZ 2019-03-03 16:51:37 +08:00 via Android
i!=n 这个条件限制范围过于窄,如果你循环体内不慎对 i 进行了自增操作,那么久很有可能跳过 i=n 这个条件导致循环无法终止
|
25
Cbdy 2019-03-03 17:52:26 +08:00 via Android
第一种主要是 C 风格的,第二种主要是 C++( STL )风格的。这个在 C++ Primer 有介绍
|