Lassen Sie uns über den Unterschied zwischen den Schlüsselwörtern new und make in der Go-Sprache sprechen

PHPz
Freigeben: 2023-03-27 17:16:36
nach vorne
761 Leute haben es durchsucht

In diesem Artikel wird eine sehr häufige Frage im Vorstellungsgespräch vorgestellt. Wie häufig kommt sie vor? Dies kann der Ausgangspunkt für viele Interviews sein. Das ist der Unterschied zwischen den beiden integrierten Funktionen new und make.

Lassen Sie uns über den Unterschied zwischen den Schlüsselwörtern new und make in der Go-Sprache sprechen

Tatsächlich ist das Problem selbst nicht kompliziert: New weist nur Speicher zu, während make nur zum Initialisieren von Slice, Map und Chan verwendet werden kann.

new

new ist eine integrierte Funktion, die einen Speicher zuweist und einen Zeiger auf diesen Speicher zurückgibt.

Die Funktionssignatur lautet wie folgt:

Quellcode

// The new built-in function allocates memory. The first argument is a type, // not a value, and the value returned is a pointer to a newly // allocated zero value of that type. func new(Type) *Type
Nach dem Login kopieren

Wie aus dem obigen Code ersichtlich ist, akzeptiert die neue Funktion nur einen Parameter, nämlich einen Typ, und gibt einen Zeiger auf die Speicheradresse dieses Parameters zurück Typ.

Gleichzeitig setzt die neue Funktion den zugewiesenen Speicher auf Null, was dem Nullwert des Typs entspricht.

Verwenden

Verwenden Sie die neue Funktion, um Speicherplatz für Variablen zuzuweisen:

p1 := new(int) fmt.Printf("p1 --> %#v \n ", p1) //(*int)(0xc42000e250) fmt.Printf("p1 point to --> %#v \n ", *p1) //0 var p2 *int i := 0 p2 = &i fmt.Printf("p2 --> %#v \n ", p2) //(*int)(0xc42000e278) fmt.Printf("p2 point to --> %#v \n ", *p2) //0
Nach dem Login kopieren

Der obige Code ist äquivalent,new(int)initialisiert den zugewiesenen Speicherplatz ebenfalls auf den Nullwert von int Es ist 0 und gibt einen Zeiger auf int zurück. Dies hat den gleichen Effekt wie die direkte Deklaration und Initialisierung des Zeigers.new(int)将分配的空间初始化为 int 的零值,也就是 0,并返回 int 的指针,这和直接声明指针并初始化的效果是相同的。

当然,new 函数不仅能够为系统默认的数据类型分配空间,自定义类型也可以使用 new 函数来分配空间,如下所示:

type Student struct { name string age int } var s *Student s = new(Student) //分配空间 s.name = "zhangsan" fmt.Println(s)
Nach dem Login kopieren

这就是 new 函数,它返回的永远是类型的指针,指针指向分配类型的内存地址。需要注意的是,new 函数只会分配内存空间,但并不会初始化该内存空间。

make

make 也是用于内存分配的,但是和 new 不同,它只用于 slice、map 和 chan 的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型。因为这三种类型本身就是引用类型,所以就没有必要返回他们的指针了。

其函数签名如下:

源码

// The make built-in function allocates and initializes an object of type // slice, map, or chan (only). Like new, the first argument is a type, not a // value. Unlike new, make's return type is the same as the type of its // argument, not a pointer to it. The specification of the result depends on // the type: // Slice: The size specifies the length. The capacity of the slice is // equal to its length. A second integer argument may be provided to // specify a different capacity; it must be no smaller than the // length, so make([]int, 0, 10) allocates a slice of length 0 and // capacity 10. // Map: An empty map is allocated with enough space to hold the // specified number of elements. The size may be omitted, in which case // a small starting size is allocated. // Channel: The channel's buffer is initialized with the specified // buffer capacity. If zero, or the size is omitted, the channel is // unbuffered. func make(t Type, size ...IntegerType) Type
Nach dem Login kopieren

通过上面的代码可以看出 make 函数的t参数必须是 slice、map 和 chan 中的一个,并且返回值也是类型本身。

使用

下面用 slice 来举一个例子:

var s1 []int if s1 == nil { fmt.Printf("s1 is nil --> %#v \n ", s1) // []int(nil) } s2 := make([]int, 3) if s2 == nil { fmt.Printf("s2 is nil --> %#v \n ", s2) } else { fmt.Printf("s2 is not nill --> %#v \n ", s2)// []int{0, 0, 0} }
Nach dem Login kopieren

slice 的零值是nil,但使用 make 初始化之后,slice 内容被类型 int 的零值填充,如:[]int{0, 0, 0}

map 和 chan 也是类似的,就不多说了。

总结

通过以上分析,总结一下 new 和 make 主要区别如下:

  • make 只能用来分配及初始化类型为 slice、map 和 chan 的数据。new 可以分配任意类型的数据;

  • new 分配返回的是指针,即类型*Type。make 返回类型本身,即Type

    Natürlich kann die neue Funktion nicht nur Speicherplatz für den Standarddatentyp des Systems zuweisen, sondern auch benutzerdefinierte Typen können die neue Funktion zum Zuweisen von Speicherplatz verwenden, wie unten gezeigt:
  • rrreee
  • Dies ist die neue Funktion, sie gibt immer einen Zeiger zurück des Typs. Der Zeiger zeigt auf die Speicheradresse des zugewiesenen Typs. Es ist zu beachten, dass die neue Funktion nur Speicherplatz zuweist, den Speicherplatz jedoch nicht initialisiert.

    make

make wird auch für die Speicherzuweisung verwendet, aber im Gegensatz zu new wird es nur für die Speichererstellung von Slice, Map und Chan verwendet, und der Typ, den es zurückgibt, ist Die drei Typen selbst, nicht ihre Zeigertypen. Da diese drei Typen selbst Referenztypen sind, besteht keine Notwendigkeit, ihre Zeiger zurückzugeben.Die Funktionssignatur lautet wie folgt:

QuellcoderrreeeAus dem obigen Code können wir sehen, dass dert-Parameter des Die Make-Funktion muss Slice oder Map und Chan sein, und der Rückgabewert ist auch der Typ selbst.

Verwenden Sie Im Folgenden wird Slice verwendet, um ein Beispiel zu geben: rrreeeDer Nullwert von Slice istnil, aber nach der Initialisierung mit make , Slice Der Inhalt wird mit Nullwerten vom Typ int gefüllt, wie zum Beispiel:[]int{0, 0, 0}. map und chan sind ebenfalls ähnlich, daher werde ich nicht auf Details eingehen.

ZusammenfassungDurch die obige Analyse werden die Hauptunterschiede zwischen new und make wie folgt zusammengefasst:
    make Es kann nur zum Zuweisen und Initialisieren von Daten der Typen Slice, Map und Chan verwendet werden. new kann jede Art von Daten zuordnen; newallokation gibt einen Zeiger zurück, d. h. Typ *Type. make gibt den Typ selbst zurück, d. h. Type; new Der zugewiesene Speicherplatz wird gelöscht. Nachdem make den Speicherplatz zugewiesen hat, wird er initialisiert

Das obige ist der detaillierte Inhalt vonLassen Sie uns über den Unterschied zwischen den Schlüsselwörtern new und make in der Go-Sprache sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:juejin.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!