2016-04-25 11 views
3

Es gibt verschiedene Bibliotheken in NIM, die tatsächliche Objekte anstelle von Referenzen zurückgeben. Manchmal möchte ich ein Objekt auf dem Heap (unabhängig von der Effizienz) - zum Beispiel, wenn ich eine generische Prozedur habe, die eine Referenz auf ein Objekt erwartet.Wie erstellt man einen IntSet auf dem Heap in Nim?

Der einzige Weg, um eine IntSet auf dem Heap ich gefunden habe, zu konstruieren ist:

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

Dies scheint zu funktionieren, aber fühlt sich wie ein Hack. Ich mache mir Sorgen, wenn es nur zu funktionieren scheint. (Sind die Strukturen durch "Zuweisen" richtig aufgeräumt?) Gibt es einen besseren Weg? Gibt es eine allgemeinere Methode, die mit anderen Objekten funktioniert?

Antwort

5

Ihr Code ist absolut gültig. Die resultierende Referenz unterliegt der Müllabfuhr wie jede andere Referenz.

Wenn Sie sich selbst finden dies oft tun, können Sie die folgende makeRef Vorlage definieren, um die Codewiederholung loszuwerden:

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

Hier ist ein Beispiel für die Verwendung:

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 

denen Ausgang :

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

Ok ... hmm ... wird das mit IntSet funktionieren (zum Beispiel): Sie benutzen 'heapVal ue [] = initExp'. Dies kann zu Problemen führen, da der von 'initExp' zurückgegebene Stapelwert mit einer seichten Kopie kopiert wird (anstatt 'assign'). Wenn das Objekt einen Destruktor hat, wird es ausgeführt, wenn das Stapelobjekt den Gültigkeitsbereich der Elemente verlässt auf das Heap-Objekt gezeigt? – shaunc

+0

Nim verwendet eine ähnliche Technik wie C++ [Rückgabewertoptimierung] (https://en.wikipedia.org/wiki/Return_value_optimization). Wenn Sie sich den generierten Code ansehen, werden Sie sehen, dass der Speicher für das Foo-Objekt zuerst auf dem Heap zugewiesen wird und dann die Adresse an die createFoo-Funktion übergeben wird, die die Konstruktion an Ort und Stelle durchführt. In diesem speziellen Fall gibt es keine Kopieroperation. – zah

+0

Sie haben die Frage nach Destruktoren nicht beantwortet .... Ich selbst versuche die Warnung (zweimal!): "Verwendung eines Typs mit einem Destruktor in einem nicht zerstörbaren Kontext." wenn ich "makeRef" mit einem Objekt mit einem Destruktor verwende. Es scheint also, dass Nim * denkt * das Objekt ist auf dem Stapel, zumindest Wetter oder nicht, es bringt es tatsächlich dort hin. Vielleicht wird das irgendwie gelöst, da Destruktoren {.experimentell.} – shaunc

Verwandte Themen