Go中的结构初始化和方法声明

I am new of Go, and pretty curious of structs. Let's define a struct T

type T struct {
    size int
}
  1. I have seen different types of struct initialization. What are the differences?

    new(T)     // 1
    T{size:1}  // 2
    &T{size:1} // 3
    
  2. And the two types of method declarations:

    func (r *T) area() int // 1
    func (r T) area() int  // 2
    

    What should be the right way?

  1. allocation

new and &T{size:1} returns *T

T{size:1} return T

The built-in function new takes a type T, allocates storage for a variable of that type at run time, and returns a value of type *T pointing to it. The variable is initialized as described in the section on initial values.

2.

The method set of any other named type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T).

var pt *T

var t T

func (r *T) area() int

you can use pt.area() or t.area()

func (r T) area() int

you can use t.area(), can't use pt.area()

usually we use func(r *T) area() int

Here are different examples:

type Animal struct {
    Legs      int
    Kingdom   string
    Carnivore bool
}

Initialization by reference

Return the pointer to the struct

var tiger = &Animal{4, "mammalia", true}

fmt.Println(tiger.Kingdom) // print "mammalia"

func changeKingdom(a *Animal) {
    a.Kingdom = "alien"    // modify original struct
}

changeKingdom(tiger) 
fmt.Println(tiger.Kingdom) // print "alien"

Constructor New Initializaiton

Return a pointer with zero-ed values

var xAnimal = New(Animal)

fmt.Println(xAnimal.Kingdom)   // print ""
fmt.Println(xAnimal.Legs)      // print 0
fmt.Println(xAnimal.carnivore) // print false

changeKingdom(xAnimal)
fmt.Println(xAnimal.Kingdom)   // print "alien"

Initialization by value (copy)

Return a separate copy of the original struct

var giraffe = Animal{4, "mammalia", false}

fmt.Println(giraffe.Kingdom) // print "mammalia"

func changeKingdom(a Animal) {
    a.Kingdom = "extraterrestrial"
}

changeKingdom(giraffe)
fmt.Println(giraffe) // print "mammalia"

More often you'll deal with pointers when using structs than the copies.