Variables F#理解循环变量可变?
在一个列表中。e、 g.使用的变量是否为与let stmt中状态相同的实变量?如果是这样,它实际上是可变的,对吗?它被绑定到一个新的东西上 每次循环都是正确的?不,它不是可变变量。我们可以通过创建稍后调用以打印它的函数来看到这一点 注意:Variables F#理解循环变量可变?,variables,f#,list-comprehension,mutable,Variables,F#,List Comprehension,Mutable,在一个列表中。e、 g.使用的变量是否为与let stmt中状态相同的实变量?如果是这样,它实际上是可变的,对吗?它被绑定到一个新的东西上 每次循环都是正确的?不,它不是可变变量。我们可以通过创建稍后调用以打印它的函数来看到这一点 注意: let printIs = [for i in 1..10 do yield fun () -> printf "%i " i] printIs |> List.iter (fun f -> f()) 这将返回: 请注意,每个1..10值
let printIs = [for i in 1..10 do yield fun () -> printf "%i " i]
printIs |> List.iter (fun f -> f())
这将返回:
请注意,每个1..10值都是打印的,因此i
不能是可变变量,因为如果是,则在循环完成后,i
将始终具有值10
。实际上,符号i
指的是列表中每一步的不同不可变值
如果我尝试使用一个实际的可变变量
x
,我会得到不同的行为:
let mutable x = 1
let printIs2 =
[for i in 1..10 do
x <- i
yield fun () -> printf "%i " x]
printIs2 |> List.iter (fun f -> f())
但是你循环中的“我”会变异,不是吗?它从1到10依次取值。@user1443098否,它不会变异。如果它确实发生了变异,它的行为将与第二个示例类似,并且每次打印
10
,因为我们在循环完成后打印值。相反,这告诉您,i
在列表理解的每一步都引用不同的不可变值。啊!这就是我错过的一点!所以,“我每次都引用不同的不可变值”非常感谢!我发现Python中的等效代码产生不同的结果很有趣:printIs=[lambda:print(I)for I in range(1,11)];对于printIs中的f:f()
确实可以打印10。但这是因为Python的后期绑定行为IIUC,当lambda被调用时,我的值是10。回答不错。顺便说一句:这导致了第5版C#的突破性改变。问题不一样,但性质非常相似。
let mutable x = 1
let printIs2 =
[for i in 1..10 do
x <- i
yield fun () -> printf "%i " x]
printIs2 |> List.iter (fun f -> f())
10 10 10 10 10 10 10 10 10 10