Make writing a habit together! This is my third day of digging Gold Day New Plan April Challenge,Click here for more details.

This article is based on Golang 1.17.2

Panghu is sitting at his desk eating the steamed stuffed bun he just bought.

The new primary school younger sister hurried to run over, flustered zhang Zhang said: “senior, not good, the online code appeared problems.”

Fat tiger hurriedly put down the steamed stuffed bun, too late to wipe the mouth, quickly took out the computer, open the computer side ask “do you know where to report wrong, why report wrong?”

Younger sister: “I don’t know…”

Fat tiger: “… All right, I’ll see for myself.”

School sister had never seen such a serious senior, the atmosphere did not dare to breathe, did not dare to go, silently look at the senior in the problem.

“Here it is, who wrote this code? Map uses new initialization.”

map1 := new(map[string]string)
Copy the code

Junior sister: “It’s me, senior…” Fat tiger: “line, see in you be my school younger sister share, today with you simple popular science once.”

The way variables are declared

 var test1 int
Copy the code

We can declare variables with var+ variable name + variable type, and when we do not assign a value to them, they will result in the zero value of the variable type.

For example, the zero value of string is “”, the zero value of int is 0, and the zero value of reference type is nil.

We can use both of these types directly, but what if we changed it to a pointer?

package main

import "fmt"

func main(a) {
  var test *string
  fmt.Println(test)
  *test = "Test"
}
Copy the code

The result is as follows:

Why? Because variables of reference type are not only declared, but also allocated memory. How do I allocate memory to it? So that’s where new comes in

What is new

New is a built-in function of Golang, the source code is as follows:

A built-in function that allocates memory. The first argument is a type, not a value, and the return value is a pointer to that type. The assigned value is a pointer to a zero value of the type.

“I know how to change,” the student excitedly said, then added two lines of code in the editor.

package main

import "fmt"

func main(a) {
  var test *string
  fmt.Println(test)
  test = new(string)
  *test = "Test"
  fmt.Println(*test)
}
Copy the code

Fat tiger: “well, good, learn very fast, then I ask you once again, composite type slice, map, chan after using new can use? Why is that?”

Student younger sister: “This you just didn’t say ah, I don’t know”

Fat tiger: “We can type the code and demonstrate.”

package main

import "fmt"

func main(a) {
  testMap := new(map[string]string)
  (*testMap)["aa"] = "aa"
  fmt.Println(testMap)
}
Copy the code

Execute the code, unexpectedly error, “this is why?”

Fat tiger: “the truth is only one, that is, map bottom is a structure, so say, you may not understand, for 🌰.”

Talk is cheap. Show me the code

package main

import "fmt"

type XueMei struct {
  age          *int64 `json:"age"`
  BoyFiriendYn bool   `json:"boy_firiend_yn"`
}

func main(a) {
  test := new(XueMei)
  // Do you have a boyfriend
  test.BoyFiriendYn = false

  // This code causes panic
  //panic: runtime error: invalid memory address or nil pointer dereference
  //[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x108a0e9]
  *test.age = 1
}
Copy the code

That is, its member variables are still uninitialized, so they need to be initialized using make.

“Senior, you know so much. Can you tell me what make is?”

What is the make

Make is also a built-in function for memory allocation, but unlike new, the source code is shown below.

The make function allocates and initializes an object of type Slice, map, or chan. Like the new function, the first argument is a type, not a value.

Unlike new, make returns the same type as its argument, not a pointer to it. The result depends on the type passed in.

When slice is made, the second parameter must be passed, which is the length of the slice. Otherwise, the compilation fails.

New function underlying implementation

New function calls go1.17 / SRC/bottom mainly runtime/malloc newobject method in the go.

Edit to center

(Optional) Add image annotations in 140 characters or less

As you can see here, when the underlying call to mallocGC was made, NeedZero passed true, so the return value is a pointer to the passed type zero.

The underlying implementation of the make function

Run the go tool compile -n -l -s file.go command

We can see the make function initialization

Slice calls a runtime.makeslice and runtime.makeslice64 methods.

func makeslice(typ *byte.len int.cap int) unsafe.Pointer
func makeslice64(typ *byte.len int64.cap int64) unsafe.Pointer
Copy the code

Edit to center

(Optional) Add image annotations in 140 characters or less

The map invokes runtime.makemap64, Runtime. makemap, and Runtime. makemap_small.

func makemap64(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
func makemap_small(a) (hmap map[any]any)
Copy the code

Chan calls the runtime.makechan64 and Runtime. makechan methods, respectively.

func makechan64(chanType *byte, size int64) (hchan chan any)
func makechan(chanType *byte, size int) (hchan chan any)
Copy the code

Interested students can go to see the source code

Student younger sister: understand senior, that I sum up

Fat tiger: “boon, quite good, as expected did not see wrong you, this evening have time, share with everybody the knowledge that you learn today.”

Student younger sister: “Can I take a rain check? My boyfriend invited me to dinner tonight.”

Fat tiger OS: at the beginning of the interview she said no boyfriend, just recruit her come in, how now suddenly have a boyfriend? I didn’t know the clown was me

More quality technical articles welcome to pay attention to the public number [back-end time]

If it helps, give it a thumbs up. thank you