Go language introduction series (5) the use of pointers and structures

Time:2021-10-24

Previous articles in the go language introduction series:

  • Basic grammar summary of go language introduction series (2)
  • Go language introduction series (3) arrays and slices
  • Go language introduction series (IV) the use of map

1. Pointer

If you have used C or C + +, you must be familiar with the concept of pointer.

We need to introduce two concepts first: memory and address.

1.1. Memory and address

The code we write is stored in external memory (drive C and drive d). For example, I existD:\Work\Program\goDirectory. If you want to run your code, you must first load your code into memory, and then give it to the CPU for calculation, and the results of CPU calculation will also be stored in memory.

The access speed of memory is fast, in which many storage units are used to store data, and the CPU can directly find these data in memory. This is because each location in memory has a unique address ID. Memory can be regarded as a building with many rooms. Each storage unit is a room. The stored data is the items in the room, and the address is the room number.

Therefore, for the CPU, if we want to find items in a room (get data from memory) or put items in a room (store data in memory), we must know the room number (memory address).

The memory address is usually a string of hexadecimal digits. If you need to write such a string of digits when saving an integer 1 or taking an integer 1 when writing code, it’s too troublesome. Therefore, high-level language provides us with a convenience to replace this string of numbers with “names” that we can remember.

These “names” areVariable name

var a int = 1
var b int = 2
var c int = 333
var d int = 6666

The association between variable name and address is done by the compiler for us, and the hardware access is still the memory address.

1.2. What is a pointer?

Simply put, the pointer is also a variable, but what is stored in this variable is not the equivalent of 1, 2, 3, “hello” and true, but the address of other variables.

The pointer is named because of the pointer variablebVariables are saved inaWe can use the pointer variablebFind variablea, if the drawing looks, it looks like a pointerbPoints to the variablea

You can also have pointers with pointers:

1.3. Use of pointer

Declare a pointer:

var p *int

*intexpresspIt’s aintType pointer,pStored in the pointer is aintThe address of the type variable, which meanspAddresses of variables of other types cannot be stored in.

How to get the address of a variable? Using operators&

Var a int = 66 // A is an int variable with a value of 66
P = & A // assign the address of a to the pointer P

So how to find the corresponding variable according to the address in the pointer? Using operators*

Var B = * P // find a according to the value in P and assign its value to B
fmt.Println(b) //66

*P = 99 // find a according to the value in P and change the value of A
fmt.Println(a) //99

Be sure to pay attention to the initialization of the pointer. If it is not initialized, the value of the pointer is its zero value——nil。 Assigning a value to an uninitialized pointer causes a problem:

Var p * int // only declared, uninitialized
*P = 12 // an error is reported: invalid memory address or nil pointer dereference

The reason is the pointerpIt’s not worth it. It’s anilNaturally, variables cannot be found based on the address.If you want to use a pointer, you must first ensure that there is a legal memory address in your pointer.It should read:

var a int
Var p * int = & A // P is initialized to the address of A
*P = 12 // find a according to the value of P, and assign 12 to a
//Or
var a int
var p *int
P = & A // the address of a is assigned to P
*P = 12 // find a according to the value of P, and assign 12 to a

Here is a complete example:

package main

import "fmt"

func main() {
	Var a int = 66 // variable a
	Var p * int = & A // pointer P points to a
	Var B = * P // get the value of variable a pointed to by P
	fmt.Println("a =",a, ", b =", b, ", p =", p)
	FMT. Println ("A's address =", & A, ", B's address =", & B, ", P's address =", & P)

	*P = 12 // change the value of variable a pointed to by P

	fmt.Println("a =",a, ", b =", b, ", p =", p)
	FMT. Println ("A's address =", & A, ", B's address =", & B, ", P's address =", & P)

	Var PP * * int = & P // pointer PP points to pointer p
	Var C = * PP // get the value of P pointed to by PP
	Var d = * * PP // get the value of a pointed to by P
	fmt.Println("pp =", pp, ", c =", c, ", d =", d)
	FMT. Println ("PP's address =", & PP, ", C's address =", & C, ", D's address =", & D ")
}

2. Structure

2.1. Basic use

Like C language, go language also has structures.

A structure is a collection of fields / attributes。 With structures, we can define our own types according to our own needs. For example, dogs cannot be represented by basic data types, because dogs have many attributes:stringName of typeintType, age, etc. a dog is a collection with many attributes. In other words, a dog is a structure. We can define adogType to represent the dog.

Declaration method of structure:

Type structure name struct{
    Field name 1 type 1
    Field name 2 type 2
    ...
}

Here is the structuredogDeclaration of:

type dog struct {
    name string
    age int
}

Once the structure is declared, you can use it.

First, as long as you declare the structure correctly, you can use it likeintstringDeclare variables like basic typesdogType, and then you can give the declared variabledThe field is assigned,Through point.To access the fields of the structure

Var D dog // declare a variable D of dog type
d. Name = "howling dog"
d.age = 3

In addition, there are several ways to declare.

You can assign values directly in field order

D: = dog {"howling dog", 3}

Or specify a field assignment so that the field order can be ignored:

D: = dog {age: 3, name: "howling dog"}

Here is a complete example:

package main

import "fmt"

type dog struct {
	name string
	age int
}

func main() {
	Var D dog // declare a variable D of dog type
	d. Name = "howling dog"
	d.age = 3

	D1: = dog {"ground dog", 2}
	
	D2: = dog {age: 4, name: "howling dog"}

	fmt.Println(d, d1, d2)
}

2.2. Structure pointer

We can get the pointer of the structure:

D: = dog {"ground dog", 2}
P: = & D // get the address of D

Its fields can be accessed according to the structure pointer:

n := (*p).name
FMT. Println (n) // howling dog

This method is troublesome. The go language provides implicit indirect references:

N: = p.name // that's OK
fmt.Println(n)

We can passnewFunction assigns a pointer to the structure.

Let’s introduce it firstnewFunction:newThe function is used to allocate various types of memory.new(T)Will giveTType allocates the appropriate memory space for it, usingTType and returns its address, which is a*TValue of type. In other words, the function returns a pointer toTPointer to a value of type zero.

p := new(dog)
fmt.Printf("%T\n", p) //*main.dog
fmt.Println(p) //&{ 0}
fmt.Println(*p) //{ 0}

As can also be seen from the three lines printed above,new(dog)A pointer is returned.

2.3. Structure nesting

One structure can also be used as a field of another structure. Here is an example:

package main

import "fmt"

type people struct {
	name string
	age int
	d dog
}

type dog struct {
	name string
	age int
}

func main() {
	A: = people {"xingxiaoguan", 18, dog {"puppy", 2}}
	FMT. Println (a) // {line Xiaoguan 18 {puppy 2}}
	FMT. Println (A.D) // {puppy 2}
	FMT. Println (a.name) // line view
	FMT. Println (a.d.name) // dog
}

Anonymous fields can also be used. What is an anonymous field? As the name suggests, only types are provided, and field names are not written:

package main

import "fmt"

type people struct {
	name string
	age int
	Dog // anonymous field
}

type dog struct {
	name string
	age int
}

func main() {
	A: = people {"xingxiaoguan", 18, dog {"puppy", 2}}
	FMT. Println (a) // {line Xiaoguan 18 {puppy 2}}
	FMT. Println (a.dog) // {puppy 2}
	FMT. Println (a.name) // line view
	FMT. Println (a.dog. Name) // dog
}

Introduction to the author

I am “xingxiaoguan”, an ordinary person among thousands of people. I have embarked on the road of programming by mistake. Since I have embarked on this road, I will go as far as possible.

I will continue to update the official account of “Java”, “Go”, “data structure and algorithm”, “computer basis” and other related articles in the public number “pedestrian view”.

Welcome to pay attention. Let’s embark on the journey together.

This article belongs to the go language introduction series.

Please correct any errors.

Recommended Today

SQL exercise 20 – Modeling & Reporting

This blog is used to review and sort out the common topic modeling architecture, analysis oriented architecture and integration topic reports in data warehouse. I have uploaded these reports to GitHub. If you are interested, you can have a lookAddress:https://github.com/nino-laiqiu/TiTanI recorded a relatively complete development process in my hexo blog deployed on GitHub. You can […]