1

簡単な例があります:

struct MyStruct
    a: int
    b: int

def my_proc(): unowned list of MyStruct
    var result = new list of MyStruct
    var my_struct = MyStruct()
    for var i = 1 to 10
        my_struct.a = i
        my_struct.b = i*i
        result.add(my_struct)
    return result

init
    pass

このコードをコンパイルすると、「戻り値として使用される強い参照を持つローカル変数と、メソッドの戻り値の型が所有権を譲渡するために宣言されていません」というエラーが発生します。コンパイルが成功したコードを変更するには?

4

3 に答える 3

1

任意の時点で、オブジェクトへの参照が少なくとも 1 つ存在する必要があります。resultここでは、リストへの参照を持つ変数を作成します。あなたがそれを返すとき、あなたはそれがunowned list of MyStruct. つまり、戻り値には参照がなくresult、範囲外になるため、リストには参照がなくなり、割り当てが解除されます。

ダングリング参照を効果的に返しています。呼び出し元が参照を持つように を返すかlist of MyStruct、共有状態 (グローバル変数またはフィールド) にコピーを配置します。

于 2015-10-28T10:43:34.483 に答える
1

Genie リストは、実際にGee.List<T>はクラス型である「偽装」であるため、参照カウントされます。

また、型推論var変数は現在、常に所有変数です (Vala バグ トラッカーには、これに関するバグ レポートがあります)。

したがってresult、クラス インスタンスへの強い参照です。それを所有されていない参照として返すことはできません。

の構造体ではなくクラスを使用することを強くお勧めしますMyStruct

そうしないと、メモリ管理の問題が発生します (構造体は参照カウントされません)。

コピーと所有権について心配する必要はありません。

class MyStruct
    a: int
    b: int

def my_proc(): list of MyStruct
    var result = new list of MyStruct
    for var i = 1 to 10
        var my_struct = new MyStruct()
        my_struct.a = i
        my_struct.b = i*i
        result.add(my_struct)
    return result

init
    pass

編集:リストに複数の値を含めたい場合は、ループ内にも my_struct を割り当てる必要があります! それを反映するようにコードを更新しました。

于 2015-10-28T10:30:12.927 に答える