I. Basic Knowledge

1. Basic Data Types

  • Value Types:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
bool (1 byte)
byte (1 byte, alias of uint8)
rune (4 bytes, alias of int32, range -2^31 to 2^31)
int (32 or 64 bits, 4 or 8 bytes)
int8 (1 byte), int16 (2 bytes), int32 (4 bytes), int64 (8 bytes)
uint (32 or 64 bits, 4 or 8 bytes)
uint8 (1 byte), uint16 (2 bytes), uint32 (4 bytes), uint64 (8 bytes)
float32 (4 bytes), float64 (8 bytes)
string     // Sequence of fixed-length characters, underlying is a byte array
complex64, complex128 (default) // Complex number type
array   // Array (fixed length)
struct  // Structure
  • Reference Types (Pointer Types):
1
2
3
slice  // Slice, default value is nil
map    // Map, default value is nil
chan   // Channel, default value is nil

2. Encoding & Strings

Go’s default encoding is UTF-8.

  • Unicode: A global character encoding standard with variable-length encoding. Multiple implementations exist, such as UTF-8 and UTF-16. Character lengths range from 1 to 4 bytes. English characters typically occupy 1 byte; Chinese characters occupy 2 bytes. Each character corresponds to a hexadecimal number. Use utf8.RuneCountInString() to get the length of a Unicode string.
  • UTF-8: A variable-length character encoding, one implementation of Unicode. English characters take 1 byte, Chinese characters take 3 bytes, emojis take 4 bytes.

Go has two types of characters: byte and rune.

  • byte: Alias of uint8, commonly used for handling ASCII characters. Represents an ASCII string. Use []byte(s) to convert string s into a byte array.
  • rune: Alias of int32, equivalent to int32. Typically used to represent a Unicode code point, capable of handling any character. Use []rune(s) to convert string s into a Unicode rune array.

string: A sequence of fixed-length characters, internally implemented as a byte array. Strings are immutable. When strings contain only letters and digits, they can be converted to []byte or []rune. For multi-byte encoded characters like Chinese, conversion to []rune is required. The most universal method is []rune(s).

  • Single quotes: Used to denote byte or rune types. Default is rune. Content inside single quotes is an ASCII character. Use len() to get the length of an ASCII string.
  • Double quotes: Denote a string literal that supports escape sequences but cannot span multiple lines.
  • Backticks: Used to create raw string literals, supporting no escape sequences and allowing multiline content. Commonly used for writing multi-line messages, HTML, regular expressions, etc.

3. Built-in Functions

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
append  // Append elements to arrays or slices, returns modified array/slice
close   // Primarily used to close channels
delete  // Remove key-value pair from map
panic   // Stop normal goroutine execution (used with recover for error handling)
recover // Allows program-defined recovery from panic in goroutines
real    // Return real part of complex number (complex, real, imag for creating/manipulating complex numbers)
imag    // Return imaginary part of complex number
make    // Allocate memory, return the Type itself (only valid for slice, map, channel)
new     // Allocate memory, primarily for value types like int, struct, return pointer to type
cap     // Return maximum capacity of a type (only valid for slice and map)
copy    // Copy elements from one slice to another, return number of copied elements
len     // Get length (e.g., string, array, slice, map, channel)
print, println // Low-level print functions

II. Common Placeholders:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Placeholder  Description                            Example                     Output
%v         Default format of the value           Printf("%v", people)        {zhangsan}
%+v        Include field names when printing structs  Printf("%+v", people)    {Name:zhangsan}
%#v        Go syntax representation of the value   Printf("#v", people)      main.Human{Name:"zhangsan"}
%T         Go syntax representation of the type    Printf("%T", people)      main.Human
%%         Literal percent sign, not a value placeholder  Printf("%%")          %
%t         Boolean placeholder (true or false)     Printf("%t", true)        true
%c         Character placeholder, corresponding Unicode code point  Printf("%c", 0x4E2D)  中
%d         Integer placeholder, decimal representation  Printf("%d", 0x12)       18
%s         String placeholder (string type or []byte)  Printf("%s", []byte("Go语言"))  Go语言
%p         Pointer placeholder, hexadecimal with prefix 0x  Printf("%p", &people)     0x4f57f0

III. Arrays, Slices, and Maps

1. Arrays

var array_variable_name [number_of_elements]type

Array length must be a constant; once defined, it cannot change. Elements within the array can be modified.

1
var a [5]int

Declares an array of length 5 with type int.

1
2
3
4
5
6
a := [8]int{0, 1, 2, 3, 4, 5, 6, 7}
b := a[3:6]
// 8 8
fmt.Println(len(a), cap(a))
// Value: [3 4 5], Length: 3, Capacity: 5
fmt.Printf("Value: %d, Length: %d, Capacity: %d", b, len(b), cap(b))

2. Slices

A flexible, variable-length sequence of elements of the same type. Slices are built on top of arrays and support automatic resizing. Slices are reference types, internally containing address, length (len), and capacity (cap).

Syntax: var slice_variable_name []type

1
2
3
4
5
6
7
8
var a []string // Declares a slice of length 0, type string
var a []string{} // Declares a slice of length 0, type string, initialized

var myslice = []string{"Beijing", "Shanghai", "Shenzhen"}

for i := 0; i < len(myslice); i++ {
   fmt.Println("for loop:", myslice[i])
}

3. Maps

An unordered data structure based on key-value pairs. In Go, maps are reference types and must be initialized using make before use.

Syntax: map[key_type]value_type

Maps have a default initial value of nil. Memory must be allocated using the make() function. Note: cap does not apply to maps—cap returns the allocated space size of a slice/array. To get the map’s capacity, use len().

1
2
3
4
5
6
7
userInfo := map[string]string{
   "username": "xiaoli",
   "password": "1234556",
}
for k, v := range userInfo {
   fmt.Println(k, v, len(userInfo))
}

IV. Pointers

In Go, reference types require declaration and memory allocation; otherwise, values cannot be stored. For value types, memory is automatically allocated during declaration.

1
2
3
4
Pointer address: &a
Pointer dereference: *&a
Pointer type: &a → *int
& gets address, * dereferences to value
  • new: Allocates memory for a type and returns a pointer. Useful for instantiating structs, returning the pointer address of the struct.
  • make: Only used for creating memory for chan, map, and slice. Returns the actual type, not a pointer.

V. Structs

Go does not have classes or class inheritance. Instead, it uses structs combined with interfaces to achieve higher extensibility and flexibility compared to traditional object-oriented programming.

1. Ways to Instantiate Structs

Direct assignment (var), new, and key-value initialization.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import "fmt"

// Define a struct
type member struct {
	name string
	city string
	age  int
}

func main() {
	var p1 member // Direct assignment instantiation
	p1.name = "Xiaoming"
	p1.city = "Beijing"
	p1.age = 32

	var p2 = new(member) // Instantiation using new
	p2.name = "Xiaoli"
	p2.city = "Shanghai"
	p2.age = 20

	p3 := &member{
		name: "Xiao Zhang",
		city: "Shenzhen",
		age:  18,
	} // Key-value initialization
	fmt.Printf("p1=%v \n", p1) // Output value
	fmt.Printf("p1=%+v \n", p1) // Output struct with field names
	fmt.Printf("p2=%#v \n", p2) // Output struct fields with Go syntax
	fmt.Printf("p3=%#v \n", p3)
}

Output:

1
2
3
4
p1={Xiaoming Beijing 32}
p1={name:Xiaoming city:Beijing age:32}
p2=&main.member{name:"Xiaoli", city:"Shanghai", age:20}
p3=&main.member{name:"Xiao Zhang", city:"Shenzhen", age:18}

2. Struct Methods and Receivers

In Go, methods are functions associated with a specific type, called the receiver. The receiver concept is similar to this or self in other languages.

Syntax:

1
2
func (receiver_variable receiver_type) method_name(parameter_list) (return_values) {
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import "fmt"

// Define a struct
type Person struct {
   name string
   age  int
   city string
}

// Value receiver
func (p Person) printInfo() {
   fmt.Printf("Name: %s, Age: %d, City: %s\n", p.name, p.age, p.city)
}

// Pointer receiver
func (p *Person) setInfo(name string, age int, city string) {
   p.name = name
   p.age = age
   p.city = city
}

func main() {
   // Instantiate struct
   p1 := Person{
      name: "Xiaoming",
      age:  15,
      city: "Tianjin",
   }
   p1.printInfo() // Name: Xiaoming, Age: 15, City: Tianjin
   p1.setInfo("Tiantian", 18, "Beijing")
   p1.printInfo() // Name: Tiantian, Age: 18, City: Beijing
}