2016-04-25 7 views
3

nimには、参照ではなく実際のオブジェクトを返すさまざまなライブラリがあります。ときには、ヒープ上のオブジェクト(効率に関係なく)が必要になることがあります。たとえば、オブジェクトへの参照が必要な一般的なプロシージャがある場合などです。nimのヒープにIntSetを作成する方法は?

私が発見したヒープ上INTSETを構築する唯一の方法は次のとおりです。

proc newIntSet() : ref IntSet = 
    new(result) 
    assign(result[], initIntSet()) 

これが動作しているようですが、ハックのように感じています。私はそれがうまくいくように思えば心配です。 (「割り当て」によってコピーされた構造が適切にクリーンアップされていますか?)良い方法はありますか?他のオブジェクトと連携するより一般的な方法がありますか?

答えて

5

あなたのコードは完全に有効です。結果として得られる参照は、他のいかなる謝辞と同様にガベージコレクションの対象となります。

あなた自身が、多くの場合、これをやって見つけた場合、あなたは以下のmakeRefテンプレートを定義することができますが、コードの重複を取り除くために:

import typetraits 

type Foo = object 
    str: string 

proc createFoo(s: string): Foo = 
    result.str = s 

let x = makeRef createFoo("bar") 
let y = makeRef Foo(str: "baz") 

echo "x: ", x.type.name, " with x.str = ", x.str 

の出力は以下となります。ここでは

template makeRef(initExp: typed): expr = 
    var heapValue = new(type(initExp)) 
    heapValue[] = initExp 
    heapValue 

は使用例です:

x: ref Foo with x.str = bar 
+0

Ok ... hmm ...これはIntSet(たとえば)で動作します:あなたは 'heapVal ue [] = initExp'です。これは 'initExp'によって返されたスタック値が(' assign'を使用するのではなく)浅いコピーを使ってコピーされるので問題を引き起こす可能性があります。オブジェクトがデストラクタを持っている場合、スタックオブジェクトが要素のスコープから外れるとヒープオブジェクトによって指されていますか? – shaunc

+0

NimはC++の[戻り値の最適化](https://en.wikipedia.org/wiki/Return_value_optimization)と同様の手法を使用します。生成されたコードを見ると、Fooオブジェクトのメモリが最初にヒープ上に割り当てられ、次にアドレスがcreateFoo関数に渡され、その場所で構築が実行されることがわかります。この特定の場合にコピー操作はありません。 – zah

+0

あなたはデストラクタに関する質問に答えませんでした。自分自身を試して、私は警告を受け取ります(2回!):「非破壊的な状況でデストラクタを持つ型の使用」デストラクタを持つオブジェクトで "makeRef"を使用するとします。だから、nim *は、オブジェクトがスタック上にあると思っているようです。少なくとも、天気かどうかは、実際にそこに置かれます。おそらくこれはデストラクタが{実験的なもの}のように何とか解決されるでしょう。 – shaunc

関連する問題