Kur*_*ren 1 f# pass-by-reference computation-expression
此 F# 代码无法编译:
let DoubleString (str : string) = str + str
let ExampleSetString (str : string byref) =
async {
str <- DoubleString str
return 1
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息str <- DoubleString str:
byref 类型变量“str”的使用方式无效。Byref 不能被闭包捕获或传递给内部函数
我必须采用 byref 变量,将其传递到计算表达式中的一些纯函数中,然后设置此 byref 变量的值。我怎样才能做到这一点?
Dotnet 限制将 byref 变量存储到字段中,因为 byref 可以指向
&ar[42])&myObject.MyField)&myLocalVar)&(System.Runtime.CompilerServices.Unsafe.AsRef<myStruct> myVar))这会导致生命周期问题:引用的寿命可能比它所指向的变量还要长。情况 1 不会发生这种情况,但所有其他项目都可能发生。例如,给定的函数Foo调用Bar和通过引用传递值将产生此堆栈
Baz function Foo function Bar function
/ \ / \ / \
--------------|---a----------|----b---------
Run Code Online (Sandbox Code Playgroud)
Foo已调用Bar并传递它a作为参考&a。Bar已将 的地址存储a到变量 中b。这意味着它b是 byref 变量,该变量的更新将更改 中的值a。当函数完成其工作时,内存被释放并且可以被其他函数重用。
Baz function Egg function
/ \ / \
--------------|---c----------
Run Code Online (Sandbox Code Playgroud)
Baz已经调用了Egg函数,现在在内存中anow 位于何处c。尝试将引用更改为anow 可能会导致各种内存问题,从AccessViolation(在 Linux 中也称为分段错误)到数据损坏。当内存损坏时可能发生的最糟糕的事情是程序继续其工作。
这就是为什么 byref 变量不能被捕获到由计算表达式产生的闭包中的原因。
现在让我们回到实际问题 - 存储 Azure blob 中的字符串。我对此不熟悉,但我找到了这方面的示例,可以将其改编为以下内容
Baz function Foo function Bar function
/ \ / \ / \
--------------|---a----------|----b---------
Run Code Online (Sandbox Code Playgroud)