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

ダニエルが指摘した参照に詳細を追加すると、問題は型'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 に答える