我不小心在嵌套的for循环中使用了两次相同的计数器:
for i in 1:2
println(i)
for j in 1:2
for i in 5:6
i += 1
println(i, " ", j)
end
end
end
编译无问题,生成
1
6 1
7 1
6 2
7 2
2
6 1
7 1
6 2
7 2
当我意识到发生了什么事时,我大吃一惊。这种行为是有意的吗?由于这会导致意外行为,是否有任何方法使编译器将其标记为错误?作为一个例子,Fortran在编译类似的代码时会抛出错误:
program testfor
integer :: i, j, k
do i = 1,2
do j = 1,2
do i = 5,6
i = i+1
write(*,*) i, j
end do
end do
end do
end program testfor
保存为ftest.f90
,然后用$:gfortran ftest.f90 -o ftest
编译显示两个错误:
ftest.f90:7:18:
5 | do i = 1,2
| 2
6 | do j = 1,2
7 | do i = 5,6
| 1
Error: Variable 'i' at (1) cannot be redefined inside loop beginning at (2)
ftest.f90:8:19:
7 | do i = 5,6
| 2
8 | i = i+1
| 1
Error: Variable 'i' at (1) cannot be redefined inside loop beginning at (2)
简短回答:是的,这是完全有意的,绝对合理和一致的。
长答:在你的代码中有两件事情导致了观察到的行为,这是值得指出的。
-
名称阴影(如上所述)。实际上这里有三个独立的变量,其中两个恰好叫做
i
。虽然内部i
范围内,没有办法访问外i
。 -
范围内循环。从您编写代码的方式来看,我假设您期望这种
for
循环像在C中一样运行,例如:让我们有一个循环变量,它在每个循环中递增。至少最内层循环中显式的额外增量表明了这一点。然而,在Julia中,for循环遍历可迭代对象,在本例中是Range
对象。最重要的部分是:迭代的当前状态存储在一个隐藏变量中。迭代变量的值对状态绝对没有影响。因此,增加i
不会显式地影响内循环的状态,遮蔽i
也不会影响外循环的状态。两个循环都沿着预定的范围运行。