Dinge, die Sie damit machen können make
, können Sie nicht anders machen:
- Erstellen Sie einen Kanal
- Erstellen Sie eine Karte mit vorab zugewiesenem Speicherplatz
- Erstellen Sie ein Slice mit vorab zugewiesenem Speicherplatz oder mit len! = Cap
Es ist etwas schwieriger zu rechtfertigen new
. Die Hauptsache, die es einfacher macht, ist das Erstellen von Zeigern auf nicht zusammengesetzte Typen. Die beiden folgenden Funktionen sind äquivalent. Man ist nur etwas prägnanter:
func newInt1() *int { return new(int) }
func newInt2() *int {
var i int
return &i
}
m := map[string]int{}
stattm := make(map[string]int)
? Es ist nicht erforderlich, die Größe vorab zuzuweisen.Go bietet mehrere Möglichkeiten zur Speicherzuweisung und Wertinitialisierung:
&T{...}
,&someLocalVar
,new
,make
Die Zuordnung kann auch beim Erstellen von zusammengesetzten Literalen erfolgen.
new
kann verwendet werden, um Werte wie Ganzzahlen zuzuweisen,&int
ist illegal:Der Unterschied zwischen
new
undmake
lässt sich anhand des folgenden Beispiels erkennen:Angenommen, Go hat kein
new
undmake
, aber es hat die eingebaute FunktionNEW
. Dann würde der Beispielcode folgendermaßen aussehen:Das
*
wäre obligatorisch , also:Ja, Zusammenführung
new
undmake
in eine einzige integrierte Funktion ist möglich. Es ist jedoch wahrscheinlich, dass eine einzelne integrierte Funktion bei neuen Go-Programmierern zu mehr Verwirrung führen würde als zwei integrierte Funktionen.Alle oben genannten Punkte in Anbetracht, scheint es besser geeignet für
new
undmake
getrennt zu bleiben.quelle
int
das erstellt wird.make(Point)
undmake(int)
in diesen letzten 2 Zeilen?make
Die Funktion weist nur ein Objekt vom Typ Slice, Map oder Chan zu und initialisiert es. Wienew
das erste Argument ist ein Typ. Es kann aber auch ein zweites Argument sein, die Größe. Im Gegensatz zu new ist der Rückgabetyp von make derselbe wie der Typ seines Arguments und kein Zeiger darauf. Und der zugewiesene Wert wird initialisiert (nicht wie in neu auf Null gesetzt). Der Grund ist, dass Slice, Map und Chan Datenstrukturen sind. Sie müssen initialisiert werden, sonst können sie nicht verwendet werden. Dies ist der Grund, warum new () und make () unterschiedlich sein müssen.Die folgenden Beispiele aus Effective Go machen dies sehr deutlich:
quelle
new([]int)
weist es nur Speicher für [] int zu, initialisiert es jedoch nicht, sodass es einfach zurückkehrtnil
. nicht der Zeiger auf den Speicher, weil er unbrauchbar ist.make([]int)
ordnet und initialisiert, damit es verwendet werden kann, und gibt dann seine Adresse zurück.new(T)
- Ordnet Speicher zu und setzt ihn auf den Wert Null für Typ T ....das gilt
0
für int ,""
für Zeichenfolge undnil
für referenzierte Typen ( Slice , Map , Chan ).Beachten Sie, dass referenzierte Typen nur Zeiger auf einige zugrunde liegende Datenstrukturen sind , die nicht durch
new(T)
Beispiel erstellt werden : Im Falle eines Slice wird das zugrunde liegende Array nicht erstellt, sodass
new([]int)
ein Zeiger auf nichts zurückgegeben wirdmake(T)
- Ordnet Speicher für referenzierte Datentypen ( Slice , Map , Chan ) zu und initialisiert die zugrunde liegenden DatenstrukturenBeispiel: Im Falle eines Slice wird das zugrunde liegende Array mit der angegebenen Länge und Kapazität erstellt.
Beachten Sie, dass ein Array im Gegensatz zu C ein primitiver Typ in Go!
Davon abgesehen:
make(T)
verhält sich wie eine Composite-Literal-Syntaxnew(T)
verhält sich wievar
(wenn die Variable nicht initialisiert ist)Führen Sie das Programm aus
Weiterführende Literatur:
https://golang.org/doc/effective_go.html#allocation_new https://golang.org/doc/effective_go.html#allocation_make
quelle
Sie müssen
make()
Kanäle und Karten (und Slices, aber diese können auch aus Arrays erstellt werden) erstellen. Es gibt keine alternative Möglichkeit, diese zu erstellen, sodass Sie sie nichtmake()
aus Ihrem Lexikon entfernen können.Was
new()
, weiß ich nicht , aus welchem Grunde auch freihändig , warum Sie benötigen es , wenn Sie struct Syntax verwenden. Es hat jedoch eine eindeutige semantische Bedeutung: "Erstellen und Zurückgeben einer Struktur mit allen Feldern, die auf ihren Nullwert initialisiert wurden", was nützlich sein kann.quelle
Abgesehen von allem, was in Effective Go erklärt wird , besteht der Hauptunterschied zwischen
new(T)
und&T{}
darin, dass letzteres explizit eine Heap-Zuweisung durchführt. Es ist jedoch zu beachten, dass dies implementierungsabhängig ist und sich daher ändern kann.Ein Vergleich
make
mitnew
macht wenig Sinn, da beide völlig unterschiedliche Funktionen ausführen. Dies wird jedoch im verlinkten Artikel ausführlich erläutert.quelle
&T{}
explizit eine Heap-Zuweisung durchführt, ist AFAIK und basiert nicht auf irgendetwas in den Spezifikationen. Eigentlich glaube ich, dass die Escape-Analyse solche * T, wann immer möglich, genau so wie bei auf Stapel hältnew(T)
.new (T): Gibt einen Zeiger auf Typ T zurück, einen Wert vom Typ * T, weist den Speicher zu und setzt ihn auf Null. new (T) entspricht & T {} .
make (T): Gibt einen initialisierten Wert vom Typ T zurück . Es ordnet den Speicher zu und initialisiert ihn. Es wird für Slices, Karten und Kanäle verwendet.
quelle