此问题与此previous thread有关。
我按照Tomas的建议使用这个代码,一切正常:
let GetSameColorNeighs (grid:Option<Ball>[,], row, col, color:Color) =
let rec loop (row, col) = seq {
if not (row < 0 || col < 0 || row > MaxLineNumber - 1
|| col > BallsPerLine - 1) then
let ball = grid.[row,col]
match ball with
| Some(ball) ->
if (!ball.visited = false || not <| ball.color.Equals(color)) then
// Not sure what you want here - yield items using 'yield'?
// [row , col]
else
ball.visited := true
yield row, col // Add single item to results
yield! loop(row + 1, col + 1) // Add all generated to results
yield! loop(row - 1, col - 1) // -- || --
| None -> () }
loop(row, col) |> Seq.toList
上面的代码遍历“球”的数组2d并返回具有相同颜色的相邻球的索引列表。
现在我必须修改函数,它返回一个布尔值,指示列表中至少有一个球是否满足某个条件。我以这种方式更改了代码,但似乎我无法在该代码中分配一个可变值:
let GetSameColorNeighs (grid:Option<Ball>[,], row, col, color:Color) : List<int * int> * bool =
let mutable b : bool = false
let rec loop (row, col) = seq {
if not (row < 0 || col < 0 || row > MaxLineNumber - 1
|| col > BallsPerLine - 1) then
let ball = grid.[row,col]
match ball with
| Some(ball) ->
if (ball.visited = true || not <| ball.color.Equals(color)) then
()
else
//HERE's THE PROBLEM
if (ball_satisfy_a_certain_condition) then
b <- true
ball.visited := true
yield row, col // Add single item to results
yield! loop(row + 1, col + 1) // Add all generated to results
yield! loop(row - 1, col - 1) // -- || --
| None -> () }
loop(row, col) |> Seq.toList, b
似乎闭包不能获取可变变量(我不知道它的意思)。
所以我有两个问题:
答案 0 :(得分:4)
简而言之,您必须使用ref
变量而不是可变变量。
虽然可变变量在堆栈上分配,但ref
变量是基于堆的。每次调用loop
函数后,当ref
值仍然存在时,可变值将被清除。因此,只有ref
值才能在GetSameColorNeighs
中返回。
这里有很多次问过这个问题。有关更深入的讨论,请参阅The mutable variable 'i' is used in an invalid way.?和this blog post。