The difference between go make and new

Source: Internet
Author: User
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", &LT;-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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.