这不起作用:
let increment(i: int byref) = i <- i + 1
let xxx = ref 0
increment(xxx) // this expression was expected to have type
// byref<int> but here has type int ref
但这有效:
let incrementParam(a: int byref) = a <- a + 1
let mutable b = 30
incrementParam(&b)
以及:
type Incrementor =
static member Increment(i : int byref) =
i <- i + 1
let fff = ref 10
Incrementor.Increment(fff)
答案 0 :(得分:6)
因为规范是这样说的。请参阅Type Directed Conversions at Member Invocations(强调我的),尤其是以下内容:
注意:这些类型定向转换主要用于与现有基于成员的.NET库的互操作性,不适用于模块中定义的函数的调用或表达式中本地绑定的函数。
答案 1 :(得分:5)
要向Daniel指出的引用添加一些细节,问题是类型'T ref
与类型'T byref
不同,因此编译器需要插入一些转换(以便地址)。
我认为只支持成员,因为这是主要场景(调用COM互操作方法等),因为隐式转换通常会编译类型推断。类型定向转换是一种更容易的情况,编译器已经知道所需的类型('T byref
)。我想,如果在函数上允许这样做,编译器可能会推断出参数的类型实际上应该是'T ref
。
如果您想让第一个样本生效,您必须通过获取'T byref
字段的地址来显式构建contents
:
let increment(i: int byref) = i <- i + 1
let xxx = ref 0
increment(&xxx.contents)