2013-10-16 10 views

risposta

2

In entrambi i casi, una struttura di Vertex viene inizializzata nello stesso modo.

La prima espressione restituisce il valore che è una struttura Vertex inizializzata. Con le regole di allineamento di 6g, ciò significa che otterrete 8 + 8 = 16 byte della struttura di Vertex, poiché ogni float64 ha una dimensione di 8 byte. La seconda espressione alloca la memoria, sufficiente per 8 + 8 = 16 byte, la usa come una struttura Vertex, la inizializza e restituisce un puntatore, che avrà una dimensione di 4 o 8 byte, a seconda dell'architettura.

Ci sono un certo numero di differenze nella pratica. I set di metodi di questi due valori, la struttura Vertex e il puntatore * Vertex, potrebbero essere diversi. A seconda della frequenza con cui è necessario passare attorno alla struttura di Vertex, potrebbe essere o meno più efficiente passare un puntatore ad essa. Se si passa una struttura Vertex a una funzione, la funzione ottiene una copia e la struttura del Vertex non verrà mai modificata. Se si passa un vertice *, il vertice sottostante potrebbe essere modificato. Questa potrebbe o potrebbe non essere la tua intenzione :)

2

TL; DR Non c'è differenza . Se una variabile è allocata nello stack o nell'heap dipende dal suo utilizzo.

Ho eseguito un deep dive sull'assembly Go generato da vari casi di inizializzazione e chiamata. L'assemblaggio generato tra v e b è quasi lo stesso. Di particolare nota, d non è allocato nello stack .

Che cosa determina se una variabile è allocata su un heap o se lo stack allocato è il modo in cui viene utilizzato. Passare il passaggio di un puntatore a una funzione che ha utilizzato solo il parametro come valore non impone l'allocazione dell'heap a una variabile. Ma anche questo non è garantito, la specifica consente a qualsiasi compilatore di Go di spostare liberamente le variabili tra lo stack e l'heap come necessario per l'ottimizzazione o la generazione del codice. Vai a abstracts away Heap vs Stack proprio come C/C++ asporta via RAM vs Register.

http://play.golang.org/p/vJQvWPTGeR

type Vertex struct { 
    X, Y float64 
} 

func PrintPointer(v *Vertex) { 
    fmt.Println(v) 
} 

func PrintValue(v *Vertex) { 
    fmt.Println(*v) 
} 

func main() { 
    a := Vertex{3, 4} // not allocated 
    PrintValue(&a) 

    b := &Vertex{3, 4} // not allocated 
    PrintValue(b) 

    c := Vertex{3, 4} // allocated 
    PrintPointer(&c) 

    d := &Vertex{3, 4} // allocated 
    PrintPointer(d) 
} 

: tecnicamente non è vero, ma sarebbe vero se fmt.Println(*d) era stato usato al posto. Ho barato un po 'per rispondere alla domanda che pensavo avresti voluto chiedere.

Problemi correlati