In most object-oriented languages such as C++, C#, and Java, objects are passed by reference, in addition to the underlying value types, when functions pass parameters.

However, in the Go language, all types (including structs) except map, slice, and chan are passed by value.

So, how do you use a processed variable outside of a function? Only by returning a new variable?

No, you can use Pointers

Most object-oriented languages have very few pointer scenarios, but there are a lot of pointer scenarios in Go that you must understand to be a qualified Gopher.

concept

Each variable is allocated a block of memory, and the data is stored in the memory, which has an address, like a house number, through which you can find the data stored in it.

A pointer is a variable that holds this memory address.

In Go, with&Gets the address of the variable

// To illustrate the type, I use explicit variable definition methods. In practice, more often than not, ":=" is used to automatically get the type variable types
var mystr string = "Hello!"
var mystrP *string = &mystr

fmt.Println(mystrP)
Copy the code

Type the above code into the main function, go run, and print out the memory address of mystr. MystrP is the pointer variable to mystr.

with*Gets the value of the memory address to which the pointer variable points

Add a line after the previous code:

fmt.Println(*mystrPointer)
Copy the code

After go run runs, you can see the value “Hello!” printed out with mystr.

symbol*Also used to define pointer types.

Such as:

var p *int
Copy the code

Pointer Application Scenarios

In other OOP languages, you don’t need to spend too much time manipulating Pointers. In Java, C#, object references are left to the virtual machine and framework. Go often uses Pointers. There are three main reasons:

  1. In the Go language, except for map, slice, and chan, all types are passed by value in function parameters
  2. Go is not an object-oriented language, and many times structure methods need to use pointer types to implement reference structure objects
  3. A pointer is also a type in the implementation interfaceinterfaceWhen, the structure type and its pointer type implement the interface differently

I’ll walk you through each of these, interspersed with some simple code snippets. You can create a Go file input code and run it.

The pointer argument is passed in the function

The Go language is all value passing, for example:

package main

import "fmt"

func main(a) {
	i := 0
	f(i)
	fmt.Println(i)
}

func f(count int) {
	fmt.Println(count)
	count++
}
Copy the code

Results:

0
0
Copy the code

I does not change before and after execution

If you want the value of I to change after the function is called, the argument to f should be *int. Such as:

func main(a) {
	i := 0
	f(&i)
	fmt.Println(i)
}

func f(count *int) {
	fmt.Println(*count)
	(*count)++
}
Copy the code
  1. F is used to define parameters*intalternativeintDeclare that the argument is a pointer of type int
  2. When calling a function, you cannot pass an int directlyi, but to pass with&achieveiThe address of the
  3. In f, the argumentcountNow it’s a pointer, you can’t print it directly, you need to use it*Retrieves the value stored at the address to which this pointer points
  4. countThe value of + 1.
  5. Call f function, in main functionmainIn the printi.

You can see the result

0
1
Copy the code

The value of I has changed.

Struct structure pointer type method

The Go language defines methods for structures

// Define a structure type
type myStruct struct {
	Name string
}

// Define the rename method for this structure
func (m myStruct) ChangeName(newName string) {
	m.Name = newName
}

func main(a) {
	// Create the struct variable
	mystruct := myStruct{
		Name: "zeta",}// Call the rename function
	mystruct.ChangeName("Chow")

	// It didn't work
	fmt.Println(mystruct.Name)
}
Copy the code

This method does not change the value of the field inside the structure variable. Even struct methods pass struct values in methods that do not use Pointers.

Now let’s use the pointer type definition structure method instead.

Just change ChangeName and replace myStruct with *myStruct

func (m *myStruct) ChangeName(newName string) {
	m.Name = newName
}
Copy the code

Run it again and you can see that the printed name has changed.

When a method is defined using a pointer type, a variable of the structure type automatically takes the pointer type of that structure and passes the method in.

Pointer type interface implementation

I recently answered a Gopher question on a q&A platform, which basically asked why we can’t implement interface methods using structure pointer types.

Take a look at the code

// Define an interface
type myInterface interface {
	ChangeName(string)
	SayMyName()
}

// Define a structure type
type myStruct struct {
	Name string
}

// Define the rename method for this structure
func (m *myStruct) ChangeName(newName string) {
	m.Name = newName
}

func (m myStruct) SayMyName(a) {
	fmt.Println(m.Name)
}

// a function that takes an interface as an argument
func SetName(s myInterface, name string) {
	s.ChangeName(name)
}

func main(a) {
	// Create the struct variable
	mystruct := myStruct{
		Name: "zeta",
	}

	SetName(mystruct, "Chow")

	mystruct.SayMyName()
}
Copy the code

This code will not compile, will prompt

cannot use mystruct (type myStruct) as type myInterface in argument to SetName:
        myStruct does not implement myInterface (ChangeName method has pointer receiver)
Copy the code

The myStruct type does not implement the interface method ChangeName, which means func (m *myStruct) ChangeName(newName String) does not implement the interface, because it is implemented by *myStruct, not myStruct.

A change is

When SetName is called, replace mystruct with &mystruct:

SetName(&mystruct, "Chow")
Copy the code

Compile and run, successful.

Why is an interface implemented by a structure type also implemented by its pointer type, but an interface implemented by a pointer type is not implemented by the structure itself?

** The reason is that methods defined by a structure type can be called by the pointer type of that structure; When a struct type calls a method of that pointer type, it is converted to a pointer, not called directly. 六四屠杀

Mystruct implements SayMyName and ChangeName. Mystruct implements SayMyName and ChangeName. Mystruct implements SayMyName and ChangeName.


To this Go language pointer type application introduction is about the same.

To sum up:

  1. Pointers are very common in Go, so be sure to master them
  2. Go language except map, slice, chan are all value transfer, reference transfer must use pointer type
  3. The struct type definition method is careful to use pointer types
  4. When implementing an interface method, an interface function implemented using a pointer type can only be considered as a pointer type, and a method implemented using a structure type can also be considered as a pointer type.

Welcome to discuss and learn Go!!

Welcome to pay attention to the public number, and we learn programming together