Maison  >  Article  >  développement back-end  >  Parlons de la différence entre les mots-clés new et make en langage Go

Parlons de la différence entre les mots-clés new et make en langage Go

PHPz
PHPzavant
2023-03-27 16:16:17838parcourir

Cet article présentera une question d'entretien très courante. Dans quelle mesure est-elle courante ? Cela peut être le point de départ de nombreux entretiens. C'est la différence entre les deux fonctions intégrées new et make.

Parlons de la différence entre les mots-clés new et make en langage Go

En fait, le problème en lui-même n'est pas compliqué. Pour faire simple, new n'alloue que de la mémoire, tandis que make ne peut être utilisé que pour initialiser slice, map et chan.

new

new est une fonction intégrée qui alloue une mémoire et renvoie un pointeur vers cette mémoire.

La signature de la fonction est la suivante :

Code source

// 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

Comme le montre le code ci-dessus, la nouvelle fonction n'accepte qu'un seul paramètre, qui est un type, et renvoie un pointeur vers l'adresse mémoire de celui-ci. taper.

Dans le même temps, la nouvelle fonction mettra à zéro la mémoire allouée, qui est la valeur zéro du type.

Utilisez

Utilisez la nouvelle fonction pour allouer de l'espace mémoire aux variables :

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

Le code ci-dessus est équivalent, new(int) initialise l'espace alloué à la valeur zéro de int, également Il vaut 0 et renvoie un pointeur vers int. Cela a le même effet que de déclarer directement le pointeur et de l'initialiser. 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)

这就是 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

通过上面的代码可以看出 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}
}

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

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

总结

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

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

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

    Bien sûr, la nouvelle fonction peut non seulement allouer de l'espace pour le type de données par défaut du système, mais les types personnalisés peuvent également utiliser la nouvelle fonction pour allouer de l'espace, comme indiqué ci-dessous :
  • rrreee
  • C'est la nouvelle fonction, elle renvoie toujours un pointeur du type, Le pointeur pointe vers l'adresse mémoire du type alloué. Il convient de noter que la nouvelle fonction allouera uniquement de l'espace mémoire, mais n'initialisera pas l'espace mémoire.

    make

make est également utilisé pour l'allocation de mémoire, mais contrairement à new, il n'est utilisé que pour la création de mémoire de tranche, de carte et de chan, et le type qu'il renvoie est Les trois types eux-mêmes, pas leurs types de pointeurs. Étant donné que ces trois types sont eux-mêmes des types référence, il n’est pas nécessaire de renvoyer leurs pointeurs. La signature de la fonction est la suivante :

🎜Code source🎜🎜rrreee🎜D'après le code ci-dessus, nous pouvons voir que le paramètre t du La fonction make doit être slice ou map et chan, et la valeur de retour est également le type lui-même. 🎜

🎜Utilisez 🎜🎜🎜Ce qui suit utilise slice pour donner un exemple : 🎜rrreee🎜La valeur zéro de slice est nil, mais après initialisation à l'aide de make , slice Le contenu est rempli de valeurs nulles de type int, telles que : []int{0, 0, 0}. 🎜🎜map et chan sont également similaires, je n'entrerai donc pas dans les détails. 🎜

🎜Résumé🎜🎜🎜Grâce à l'analyse ci-dessus, les principales différences entre new et make sont résumées comme suit : 🎜
    🎜🎜make Il ne peut être utilisé que pour allouer et initialiser des données de types slice, map et chan. new peut allouer n'importe quel type de données ; 🎜🎜🎜🎜new allocation renvoie un pointeur, c'est-à-dire tapez *Type. make renvoie le type lui-même, c'est-à-dire Type ; 🎜🎜🎜🎜new L'espace alloué est vidé. Une fois que make a alloué de l'espace, il sera initialisé 🎜🎜🎜🎜Apprentissage recommandé : "🎜tutoriel vidéo go🎜"🎜 ;

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer