This is a creation in Article, where the information may have evolved or changed.
Both new and make can be used to allocate space, initialize types, but they do differ.
New (t) returns a pointer to T
New (t) allocates a space for a value of type T and initializes the space to the 0 value of T, returning the address of the new value, which is a pointer to the type T *t, which points to the new assigned 0 value of T.
123456789 |
New (int) FMT. Printf ("P1---#v \ n"fmt. Printf ("P1 Point-to-#v \ n"//0var p2 *int0p2 = &ifmt. Printf ("P2---#v \ n"fmt. Printf ("P2 Point-to-#v \ n"//0 |
The above code is equivalent, and new (int) initializes the allocated space to the 0 value of int, which is 0, and returns a pointer to int, which is the same effect as declaring the pointer directly and initializing it.
Make can only be used for Slice,map,channel
Make can only be used for Slice,map,channel three types, and make (T, args) returns the value of the type T after initialization, which is not a 0 value of type T, or pointer *t, which is a reference to the initialized T.
1234567891011 |
var s1 []intifnil { fmt. Printf ("S1 is nil--and% #v \ n"//[]int (nil)make ([]int3)if Nil { fmt. Printf ("S2 is nil--and% #v \ n"else { FMT. Printf ("S2 is not nill--and% #v \ n", S2)//[]int{0, 0, 0}} |
Slice's 0 value is nil, after using make slice is an initialized slice, that is, the length of the slice, the capacity, the underlying array is initialized by make, when the slice content is filled with the 0 value of type int, in the form of [0 0 0 The],map and channel are similar.
123456789101112131415161718192021222324 |
varM1Map[int]stringifM1 = =Nil{FMT. Printf ("M1 is nil--and% #v \ n", M1)//map[int]string (Nil)}M2: = Make(Map[int]string)ifM2 = =Nil{FMT. Printf ("M2 is nil--and% #v \ n", m2)}Else{FMT. Printf ("M2 is not nill--and % #v \ n", m2)Map[int]string{} }varC1Chan stringifC1 = =Nil{FMT. Printf ("C1 is nil--and% #v \ n", C1)//(Chan string) (nil)}C2: = Make(Chan string)ifC2 = =Nil{FMT. Printf ("C2 is nil--and% #v \ n", C2)}Else{FMT. Printf ("C2 is not Nill--and % #v \ n", C2)//(Chan string) (0xc420016120)} |
Make (t, args) returns a reference to T
If not specifically declared, Go's function by default is by the value of the pass parameter, that is, the argument passed by the function is a copy of the value, in the function of the value modification does not affect the value itself, but make (T, args) The value returned by the function pass parameters can be directly modified, that is Map,slice,channel Modifications within the function after a function pass will affect the value outside the function.
12345678 |
func Modifyslice (s []int) { s[01make ([]int3) fmt. Printf ("% #v"//[]int{0, 0, 0}modifyslice (s2) fmt. Printf ("% #v"//[]int{1, 0, 0} |
This means that make (T, args) returns a reference type, and the original value can be changed directly inside the function, as well as for map and channel.
12345678910111213141516171819202122232425262728 |
func modifymap(M map[int]string) {m[0] ="string"} func Modifychan(c Chan string) {C <-"string"}M2: = Make(Map[int]string)ifM2 = =Nil{FMT. Printf ("M2 is nil--and% #v \ n", m2)}Else{FMT. Printf ("M2 is not nill--and % #v \ n", m2)//map[int]string{}}modifymap (m2) fmt. Printf ("M2 is not nill--and % #v \ n", m2)///map[int]string{0: "String"}C2: = Make(Chan string)ifC2 = =Nil{FMT. Printf ("C2 is nil--and% #v \ n", C2)}Else{FMT. Printf ("C2 is not Nill--and % #v \ n", C2)}GoModifychan (C2) fmt. Printf ("C2 is not Nill--and % #v", <-C2)//"string" |
It is seldom necessary to use new
123456789101112131415161718192021222324252627282930 |
typeFoostruct{NamestringAgeint}varFoo1 foofmt.printf ("foo1--% #v \ n", foo1)//main. foo{age:0, Name: ""}Foo1.age =1Fmt. Println (foo1.age) Foo2: = Foo{}fmt. Printf ("Foo2--% #v \ n", Foo2)//main. foo{age:0, Name: ""}Foo2.age =2Fmt. Println (foo2.age) Foo3: = &foo{}fmt. Printf ("Foo3--% #v \ n", Foo3)//&main. foo{age:0, Name: ""}Foo3.age =3Fmt. Println (foo3.age) Foo4: =New(Foo) fmt. Printf ("Foo4--% #v \ n", Foo4)//&main. foo{age:0, Name: ""}Foo4.age =4Fmt. Println (Foo4.age)varFoo5 *foo =New(Foo) fmt. Printf ("Foo5--% #v \ n", FOO5)//&main. foo{age:0, Name: ""}Foo5.age =5Fmt. Println (Foo5.age) |
Foo1 and Foo2 are the same type, all Foo type values, Foo1 is declared by Var, Foo's filed is automatically initialized to 0 values of each type, Foo2 is initialized by literal completion.
Foo3,foo4 and Foo5 are the same type, all of which are the pointer *foo of Foo.
But all Foo can directly use Foo's filed, read or modify, why?
If X is addressable, the filed collection of &x contains M,X.M and (&x). M is equivalent, and go automates the conversion, that is, foo1.age and foo3.age calls are equivalent, and go is automatically converted below.
This allows you to create objects directly using struct literal, which can be the same as new creation without the need to use new.
Code in this article
Download code