2012-09-08 14 views
8

Hai una funzione con un argomento, un puntatore a un tipo.Uso di new vs var in Go

type bar struct{...} 

func foo(arg *bar) 

C'è qualche differenza tra:

var b bar 
foo(&b) 

e

b := new(bar) 
foo(b) 

L'utilizzo di nuove crea uno stanziamento.

+2

Non penso. Questa domanda richiede specificamente il risultato di '& Variable' vs' new (Type) 'quando viene passato a un tipo di puntatore che assume la funzione. 10990174 non chiede né risponde. – zzzz

risposta

10

No, non v'è alcuna differenza, come, contrariamente a C, Go esplicitamente afferma che si può dare un puntatore a una variabile creata a livello locale.

Da the documentation:

Si noti che, a differenza di C, è perfettamente OK per restituire l'indirizzo di una variabile locale ; la memoria associata alla variabile sopravvive a dopo la funzione restituisce

4

Entrambi devono rappresentare lo stesso puntatore allo stesso oggetto inizializzato con lo stesso valore predefinito.

Il spec fa menzione:

Dopo

type T struct { i int; f float64; next *T } 
t := new(T) 

vale quanto segue:

t.i == 0 
t.f == 0.0 
t.next == nil 

Lo stesso sarebbe anche vero dopo

var t T 

anche:

Prendendo l'indirizzo di un letterale composito (§ Address operators) genera un puntatore a un'istanza univoca del valore del letterale.

var pointer *Point3D = &Point3D{y: 1000} 
-3

Ci sono differenze in alcune situazioni. new(T), come suggerisce il nome, restituisce una, beh, nuova istanza di tipo T, mentre var b T è una singola istanza, una volta e per sempre (err, in realtà fino alla fine della sua durata == esce dall'ambito, non raggiungibile ...) .

considerare questo ciclo

var b bar 
for i := 0; i < 10; i++ { 
    foo(&b) 
} 

vs

var b *bar 
for i := 0; i < 10; i++ { 
    b = new(b) 
    foo(b) 
} 

In quest'ultimo caso, se foo ad esempio memorizza i suoi arg in qualche contenitore, i risultati in 10 casi di bar esistente, mentre il primo caso con solo uno - nella variabile b.

Un'altra differenza è nella prestazione. La variabile b potrebbe essere una variabile globale completamente statica o in genere si troverà in un offset noto staticamente in alcuni record di chiamata funzione/metodo (un nome di fantasia per un frame di solito). new OTOH, se non ottimizzato dal compilatore, è una chiamata allocatore di memoria. Tale chiamata avrà un costo diverso da zero. Se fatto in un ciclo e non effettivamente necessario, allora può rallentare notevolmente alcuni percorsi del codice.

+1

L'unica differenza è che new() restituisce un puntatore a una variabile mentre var consente di dichiarare una variabile. Questa risposta avrebbe senso se Go riconoscesse la differenza tra stack e heap nella lingua. Vedi la risposta di dystroy qui sotto e la mia risposta ad un'altra domanda http://stackoverflow.com/a/10990287/727643 –

+5

Questa è la risposta non è corretta. –

+0

@StephenWeinberg: resto dalla mia risposta. (Naturalmente dopo averlo ricontrollato). Si prega di specificare i difetti percepiti rispetto alle specifiche. Inoltre, per favore dimmi quale (ragionevole) alternativa all'allocazione di memoria è per l'implementazione di 'new'. Inoltre, ti preghiamo di farmi sapere quale/i compilatore/i esistente/i utilizza tale alternativa. Grazie in anticipo. Mi rendo conto che le specifiche non parlano di stack o heap. Ciò non esclude di parlare di come funziona l'implementazione, specialmente se aiuta a capire. Vedi anche: http://research.swtch.com/godata – zzzz