Downstairs opened a new Chongqing casserole fat intestine, loudspeaker has been playing: authentic old Chongqing casserole fat intestine, spicy and delicious, old ba shi.

I don’t know if it’s authentic. Anyway, I thought I went back to the northeast from my accent.

The final part of this article on complex data types: dictionaries and structs. Content is very important, programming is also used more, need to master.

All the code in this article is written based on GO1.16.6.

The dictionary

Dictionary is a very common data structure. Go is represented by the keyword MAP and the type is map[K]V. K and V are data types for the keys and values of the dictionary, respectively, where keys must support equality operators such as numbers, strings, etc.

Create a dictionary

There are two ways to create a dictionary. The second uses the built-in function make.

Literals are created:

// Create a literal
var m = map[string]int{"a": 1."b": 2}
fmt.Println(m) // map[a:1 b:2]
Copy the code

Use make to create:

// Use make to create
m1 := make(map[string]int)
fmt.Println(m1)
Copy the code

You can also initialize the length of the dictionary. When the length of the dictionary is known, directly specifying the length can improve the execution efficiency of the program.

// Specify the length
m2 := make(map[string]int.10)
fmt.Println(m2)
Copy the code

The zero value of a dictionary is nil, and assigning a value to a dictionary that is nil will cause an error.

// The zero value is nil
var m3 map[string]int
fmt.Println(m3 == nil.len(m3) == 0) // true true
// Nil assignment error
// m3["a"] = 1
// fmt.Println(m3)	// panic: assignment to entry in nil map
Copy the code

Use a dictionary

Assignment:

/ / assignment
m["c"] = 3
m["d"] = 4
fmt.Println(m) // map[a:1 b:2 c:3 d:4]
Copy the code

Values:

/ / value
fmt.Println(m["a"], m["d"]) / / 1 4
fmt.Println(m["k"])         / / 0
Copy the code

No error is reported even if the Key does not exist. Instead, return a zero value for the corresponding type.

Delete element:

/ / delete
delete(m, "c")
delete(m, "f") // The key does not exist and no error is reported
fmt.Println(m) // map[a:1 b:2 d:4]
Copy the code

Get length:

// Get the length
fmt.Println(len(m)) / / 3
Copy the code

Determine whether the key exists:

// Check whether the key exists
if value, ok := m["d"]; ok {
	fmt.Println(value) / / 4
}
Copy the code

In contrast to Python, this is pretty cool to use.

Through:

/ / traverse
for k, v := range m {
	fmt.Println(k, v)
}
Copy the code

Reference types

Map is a reference type, so when passed between functions, a copy of the map is not made, which is as efficient as slicing.

package main

import "fmt"

func main(a){.../ / the refs
	modify(m)
	fmt.Println("main: ", m) // main: map[a:1 b:2 d:4 e:10]
}

func modify(a map[string]int) {
	a["e"] = 10
	fmt.Println("modify: ", a) // modify: map[a:1 b:2 d:4 e:10]
}
Copy the code

The structure of the body

A structure is an aggregation type that contains zero or more named variables of any type, each of which is called a member of the structure.

Creating a structure

First, use type to define a structure type user with two member variables: name and age.

// Declare the structure
type user struct {
	name string
	age  int
}
Copy the code

There are two ways to initialize a structure:

The first is to assign each field in the order in which it is declared, but note that the order of the fields is strictly the same.

/ / initialization
u1 := user{"zhangsan".18}
fmt.Println(u1) // {zhangsan 18}
Copy the code

The downside of this is obvious: if the field changes incidentally, everything involved in the initialization of the structure will change as well.

Therefore, it is more recommended to use the second method, which is to initialize by the field name.

// The better way
// u := user{
// age: 20,
// }
// fmt.Println(u)	// { 20}
u := user{
	name: "zhangsan",
	age:  18,
}
fmt.Println(u) // {zhangsan 18}
Copy the code

Uninitialized fields are assigned a value of zero of the corresponding type.

Using structures

Use the dot. To access and assign member variables.

// Access the structure members
fmt.Println(u.name, u.age) // zhangsan 18
u.name = "lisi"
fmt.Println(u.name, u.age) // lisi 18
Copy the code

If the member variables of a structure are comparable, the structure is also comparable.

// Structure comparison
u2 := user{
	age:  18,
	name: "zhangsan",
}
fmt.Println(u1 == u)  // false
fmt.Println(u1 == u2) // true
Copy the code

The structure is nested

Now that we have defined a user structure, suppose we define two more admin and leader structures, as follows:

type admin struct {
	name    string
	age     int
	isAdmin bool
}

type leader struct {
	name     string
	age      int
	isLeader bool
}
Copy the code

The problem is that two fields, name and age, have been defined multiple times.

Laziness is a required course for programmers. Is there any way to reuse these two fields? The answer is struct nesting.

This is what the nested optimization looks like:

type admin struct {
	u       user
	isAdmin bool
}

type leader struct {
	u        user
	isLeader bool
}
Copy the code

The code looks a lot cleaner.

Anonymous members

It’s still not perfect, though, and it’s still a bit of a hassle every time you access a member variable of a nested structure.

// The structure is nested
a := admin{
	u:       u,
	isAdmin: true,
}
fmt.Println(a) // {{lisi 18} true}
a.u.name = "wangwu"
fmt.Println(a.u.name)  // wangwu
fmt.Println(a.u.age)   / / 18
fmt.Println(a.isAdmin) // true
Copy the code

This is where anonymous members come in, specifying not a name but only a type.

type admin1 struct {
	user
	isAdmin bool
}
Copy the code

In this way, we can omit the intermediate variables and directly access the member variables we need.

// Anonymous member
a1 := admin1{
	user:    u,
	isAdmin: true,
}
a1.age = 20
a1.isAdmin = false

fmt.Println(a1)         // {{lisi 20} false}
fmt.Println(a1.name)    // lisi
fmt.Println(a1.age)     / / 20
fmt.Println(a1.isAdmin) // false
Copy the code

conclusion

This article introduced dictionaries and structs, two very common data types. Although the space is not long, but the basic operations are covered, writing code is certainly no problem. The lower principles and more flexible uses are for you to explore and discover.

Of course, I will also share some more in-depth articles after writing the basic column. Welcome your attention and communication.

So far, that’s all about data types.

First, you learned about the basic data types, including integers, floats, complex numbers, Booleans, and strings. Then there are compound data types, including arrays, slices, dictionaries, and structures.

These are the foundation of Go, so we must practice more and master them skillfully. I have uploaded the code in the article to Github. If you need it, you can click on the address at the end of the article and download it by yourself.


The brain map and source code in the article are uploaded to GitHub, students who need to download.

Address: github.com/yongxinz/go…

List of Go columns:

  1. Development environment setup and VS Code development tools configuration

  2. Declaration and assignment of variables and constants

  3. Basic data types: integer, floating point, complex, Boolean, and string

  4. Composite data types: array and slice