【发布时间】:2012-06-08 10:40:24
【问题描述】:
我正在尝试从 java do F# 中移植一些代码,以在给定点周围生成多维点网格。我想出了这个:
let gridGenerator midpoint stepSize steps =
seq {
let n = Array.length midpoint
let direction = Array.create n -steps
let mutable lastIndex = n-1
while lastIndex>=0 do
let next = midpoint |> Array.mapi (fun i x -> x+ direction.[i]*stepSize)
while lastIndex>=0 && direction.[lastIndex]=steps do
direction.[lastIndex]<- (-steps)
lastIndex<-lastIndex-1;
if lastIndex>=0 then
direction.[lastIndex]<-direction.[lastIndex]+1;
lastIndex <- n-1;
yield next;
}
除了这段代码非常必要(我会很感激如何修复它的提示),我得到一个编译错误:
Program.fs(18,15):错误 FS0407:可变变量“lastIndex”的使用方式无效。可变变量不能被闭包捕获。考虑通过“ref”和“!”消除这种突变的使用或使用堆分配的可变参考单元。
如何解决此错误?如何让它更实用?
示例:对于中点 [|0.0, 1.0|],步长 0.5 和步长 1 我期望(实际上以任何顺序)
seq{[|-0.5, 0.5|], [|-0.5, 1.0|], [|-0.5, 1.5|], [|0.0, 0.5|], [|0.0, 1.0|], [|0.0, 1.5|], [|0.5, 0.5|], [|0.5, 1.0|], [|0.5, 1.5|]}
还请注意,这将执行多次,因此性能至关重要。
【问题讨论】:
-
“可变变量不能被闭包捕获。” F# 的严肃设计 WTF。
-
错误信息告诉你该怎么做:使用
ref。 -
@leppie - 这避免了 C# 中可能发生的一整类微妙的错误 - 例如参见 eric lipperts blog
-
@leppie 如果您不需要手动操作,为什么不用 C++ 编写代码?更好的是汇编代码——那里没有手持。
-
@leppie,有关设计原理,请参阅 lorgonblog.wordpress.com/2008/11/12/…。
标签: f#