Perché c'è un "nuovo" in Go?


49

Sono ancora perplesso sul perché abbiamo newin Go.

Quando vuoi creare un'istanza di una struttura, lo fai

t := Thing{}

e puoi ottenere un puntatore a una nuova istanza facendo

t := &Thing{}

Ma c'è anche questa possibilità:

t := new(Thing)

Quest'ultimo sembra un po 'estraneo al resto della lingua. &Thing{}è chiaro e conciso come new(Thing)e usa solo costrutti che usi spesso altrove. È anche più estensibile in quanto potresti cambiarlo in &Thing{3}o &Thing{Feets:7}.

A mio avviso, avere una parola chiave supplementare 1 è costoso, rende la lingua più complessa e aggiunge ciò che devi sapere. E potrebbe mascherare per i nuovi arrivati ​​cosa c'è dietro un'istanza di una struttura.

Fa anche un'altra parola riservata.

Quindi qual è il ragionamento dietro new? A volte è utile? Dovremmo usarlo?


1 : Sì, lo so che non è una parola chiave a livello grammaticale, puoi oscurarla , ma ciò non cambia il fatto che, per lo sviluppatore ragionevole, è una parola riservata.


3
"... to Go programmatori ..." - questa è la ragione. F # / Haskell / etc. sono molto estranei agli sviluppatori C ed è per questo che stanno ottenendo una trazione ~ 0. Scala ha fatto uno sforzo e ora è più accessibile e sentito parlare.
Den

12
Per lo stesso motivo, Python e Ruby sono molto estranei agli sviluppatori C, in quanto usano un sacco di parole chiave sconosciute, "strane" regole sintattiche (dove sono le parentesi graffe?) E strani concetti semantici (generatori? Metaclassi? Decoratori?). Eppure non ottengono una trazione ~ 0, al contrario.
Xion,

8
@Xion: hai visto il tasso di crescita iniziale di Ruby? Ci sono voluti anni per arrivare dove si trova ora (18 anni, per essere precisi). Python è ancora più vecchio (1991!).
Joachim Sauer,

2
@AndresF. Parte della resistenza alla Scala non poteva avere nulla a che fare con la lingua. Come programmatore più giovane (25 anni), qualcosa sul nome stesso mi fa pensare a un incrocio tra un linguaggio basato sulla matematica come Matlab (di cui ho brutti ricordi) e uno molto vecchio come Fortran. Non c'è mai stato alcun bisogno di guardarlo.
Izkata,

4
Una nota a margine: new non è una parola chiave in Go. È una funzione integrata.
Manish Malik,

Risposte:


44

Il modo migliore per chiedere è probabilmente alle persone che ci lavorano; esattamente quello che ho fatto !

Tl; dr: era originariamente lì prima makee &{}, ed è ancora la funzione da utilizzare in alcune situazioni.

Fondamentalmente, ecco le parti più importanti citate:

Quindi qual è il ragionamento alla base del nuovo? È qualcosa di utile? Dovremmo usarlo?

Non puoi farlo senza nuovo

v := new(int)
*v++
fmt.Println(*v)

nuovo non è una funzionalità principale di Go, non lo troverai usato spesso, ma quando ne hai bisogno, è lì.

Saluti

Dave

Dopo un'altra risposta che mostra questo tipo di soluzione:

vv := 0
v := &vv
*v++
fmt.Println(*v)

Ho chiesto ulteriori chiarimenti:

Quindi, fondamentalmente, il punto di Dave non regge davvero?

Ci sono luoghi in cui è scomodo intrufolarsi in una nuova variabile solo per prendere il suo indirizzo.

new (T) ha un significato immediatamente diretto, piuttosto che essere un linguaggio a più fasi.

Il punto di Dave cade solo se la semplice possibilità tecnica (di fare a meno new) è avvincente da sola.

Non è stato discusso perché era ovvio che Go avrebbe dovuto farlo perché quasi tutte le lingue ce l'hanno?

Il "dobbiamo mantenere new?" la discussione si apre di volta in volta. Dal momento che non possiamo eliminarlo fino a Go 2, se capisco correttamente la Promessa, sembra che non ci sia molto da fare andando di nuovo in giro; quando Go 2 è pensabile, potremmo avere idee diverse e migliori ...

Chris

È anche lì principalmente per motivi storici:

devi considerare la storia del progetto. penso che il nuovo sia introdotto prima che ci sia make.

Questo è vero. In effetti abbiamo lottato per un po 'prima di elaborare l'idea di make. Se guardi i log del repository puoi vedere che make compare solo a gennaio 2009, revisione 9a924177598f.

La nuova funzione incorporata ha anche preceduto l'idea di & {} per prendere l'indirizzo di un letterale composito (e quella sintassi è in qualche modo sbagliata; probabilmente dovrebbe essere (* T) {campi di T} ma non c'era abbastanza motivo per cambiarlo).

La nuova funzione non è strettamente necessaria ma il codice sembra usarla nella pratica. È difficile liberarsene a questo punto.

Ian


Sarei felice di vedere i collegamenti agli altri "dobbiamo rimanere nuovi?" discussioni che saltano fuori di tanto in tanto .
Denys Séguret,

Qualcosa ti impedisce di fare v := &(0)e saltare la variabile temp? (Non conosco Go.)
Alex Feinman,

3
@AlexFeinman Poiché 0è una costante letterale, non puoi prendere il suo indirizzo. Un problema potrebbe verificarsi se si desidera anche un tipo specifico. Ecco perché una sintassi gradisce &into &int(0)potrebbe essere utile (non ha pensato molto alla migliore sintassi, però). Ma farlo in due righe, come ha dimostrato Collins, va bene ( vv := 0; v := &vv).
Denys Séguret,

14
"Dato che non possiamo eliminarlo fino a Go 2" ... che, come tutti sanno, non accadrà mai perché Go 2è considerato dannoso.
Mason Wheeler,

2
@MasonWheeler mi hai quasi ucciso ... ridendo ancora di "Go 2 considerato dannoso" ... stranamente stavo parlando di quell'articolo oggi a pranzo.
Daniela Petruzalek,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.