let iter2D (map: 'T byref -> unit) (arr: 'T[][]) =
    for y = 0 to arr.Length - 1 do
        let row = arr.[y]
        for x = 0 to row.Length - 1 do
            let mutable elem = arr.[y].[x]
            map &elem

最后一行有:“此时不能使用变量‘elem’的地址。”怎么了?

最佳答案

在 F# 中 'T byref 作为常规类型出现,但实际上并非如此——它对应于 C# 中的 refout 参数,它们是方法参数上的特殊注释。这就是 'T byref 在 F# 中有点奇怪的原因。

我认为您将无法通过普通的 F# 函数使用它,因为函数 T1 -> T2 被编译为 FSharpFunc<T1, T2> 并使用 T2 Invoke(T1 arg) 方法 - 并且您不能将 byref 类型传递给泛型(因为它不是真正的类型)。

一种解决方法是定义您自己的具有 byref 类型的委托(delegate):

type FastAction<'T> = delegate of 'T byref -> unit

有了这个,您可以编写直接遍历数组的 iter2D :
let iter2D (map:FastAction<'T>) (arr: 'T[][]) =
    for y = 0 to arr.Length - 1 do
        let row = arr.[y]
        for x = 0 to row.Length - 1 do
            map.Invoke(&arr.[y].[x])

下面的代码将改变数组中的值:
let arr = [| [| 0 |] |]
iter2D (FastAction(fun a -> a <- 10)) arr

关于f# - 为什么这不是 byref 的有效用法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36537965/

10-10 13:16