3

这不起作用:

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) 
4

2 回答 2

6

因为规范是这样说的。请参阅成员调用中的类型定向转换(重点是我的),尤其是以下内容:

注意:这些类型导向的转换主要用于与现有的基于成员的 .NET 库的互操作性,不适用于调用模块中定义的函数或表达式中本地绑定的函数。

于 2013-01-25T17:17:35.093 回答
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)
于 2013-01-25T17:25:46.860 回答