F# 从 CollectionsMarshal.GetValueRefOrAddDefault 返回 byref
我试图获取从 CollectionMarshal.GetValueRefOrAddDefault
方法返回的 byref
。现在 t
是一个 int
但我想要 byref
。
open System.Runtime.InteropServices
let d = System.Collections.Generic.Dictionary<int, int>()
let t, _ = CollectionsMarshal.GetValueRefOrAddDefault (d, 1)
F# 文档说要在方法调用前添加 &
,但编译器会返回错误。
let t, _ = &CollectionsMarshal.GetValueRefOrAddDefault (d, 1)
// Error:
// Cannot take the address of the value returned from the expression.
// Assign the returned value to a let-bound value before taking the address.
// F# Compiler3236
I am trying to get the byref<int>
that is returned from the CollectionMarshal.GetValueRefOrAddDefault
method. Right now t
is an int
but I am wanting the byref<int>
.
open System.Runtime.InteropServices
let d = System.Collections.Generic.Dictionary<int, int>()
let t, _ = CollectionsMarshal.GetValueRefOrAddDefault (d, 1)
The F# docs say to prepend a &
to the method call but then the compiler returns an error.
let t, _ = &CollectionsMarshal.GetValueRefOrAddDefault (d, 1)
// Error:
// Cannot take the address of the value returned from the expression.
// Assign the returned value to a let-bound value before taking the address.
// F# Compiler3236
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里有一些示例代码来说明解决方案:
这里发生的情况是,您试图对编译器试图加糖的内容进行去糖(隐式可变占位符参数),但在我看来,编译器加糖的方式存在差距。您可以提出一个合理的论点,即
let struct(wasAdded, value) = CollectionsMarshal.GetValueRefOrAddDefault(d, 1)
可能是合理的脱糖,因为没有分配等。无论如何,在您的示例中让我们看看您尝试调用的成员的签名:
编译器有一个方法模式,该模式具有以 out/byref 值结尾并返回 byref 值的参数列表:它将执行所有操作为您记账。我的意思是,它将为您初始化
let mutable x = Unchecked.defaultof<_>
单元格,使用这些单元格的引用值调用该方法,并为您提供最终答案。因为你想做快速的事情,所以你只需要自己包装而不是让编译器脱糖。
Here's some sample code to illustrate a solution:
What's happening here is that you're trying to de-sugar what the compiler is trying to sugar (implicit mutable placeholder parameters), but there's a gap here IMO in the ways the compiler sugars things. You could make a reasonable argument that
let struct(wasAdded, value) = CollectionsMarshal.GetValueRefOrAddDefault(d, 1)
could be a reasonable desugaring, due to no allocations, etc, etc.Anyway, in your example let's look at the signature of the member you're trying to invoke:
The compiler has a pattern for methods that have parameter lists that end with out/byref values and return byref values: it will do all of the bookkeeping for you. By this I mean it will initialize the
let mutable x = Unchecked.defaultof<_>
cells for you, call the method with the ref values to those cells, and give you the final answers.Because you want to do fast things, you just need to do that wrapping yourself instead of letting the compiler desugar.