为什么这不是byref的有效用法?

Asi*_*sik 3 f# byref

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
Run Code Online (Sandbox Code Playgroud)

最后一行有:"此时不能使用变量'elem'的地址." 怎么了?

Tom*_*cek 7

在F#'T byref显示为一个常规的类型,但在盖下,它不是-其对应于refout参数在C#,而这些都是对方法参数特殊注释.这就是'T byrefF#中有点奇怪的原因.

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

解决方法是定义具有byref类型的自己的委托:

type FastAction<'T> = delegate of 'T byref -> unit
Run Code Online (Sandbox Code Playgroud)

有了这个,你可以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])
Run Code Online (Sandbox Code Playgroud)

然后,以下内容将改变数组中的值:

let arr = [| [| 0 |] |]
iter2D (FastAction(fun a -> a <- 10)) arr
Run Code Online (Sandbox Code Playgroud)