Preface: This project is used to record my (647) study and accumulation in Go language direction. This series is fairly basic and is recommended for developers who want to get started with Go. The directory is as follows: Go language foundation (1) — Introduction, environment configuration, HelloWorld Go language foundation (2) — Basic common syntax Go language foundation (3) — Object-oriented programming Go language foundation (4) — high-quality fault tolerance Go language foundation (5) — Concurrent programming Go language foundation (6) — Testing, Reflection, Unsafe Go Basics (7) — Architecture & Common Tasks Go Basics (8) — Performance Tuning


This article will cover the following: 1. How to write a Go test program? Definition of variables and constants 3. Basic data types 4. Pointer types 5. Conditions and loops 7. Arrays and slices 8.Map 9. Strings 10.


In order to make it easier to test our Go code (Go service), we will first introduce how to test our program in the Go language.

Getting started: How to write a test program?

Requirements:

  1. The source file ends with _test: xxx_test.go

  2. Func TestXXX(t * test.t){… func TestXXX(t * test.t){… }

Practical steps:

  • Create a first_test.go file.

  • Write the following code:

package try_test

import "testing"

func TestFirstTry(t *testing.T) {
	t.Log("My first try!")}Copy the code

Run under terminal:

go test first_test.go -v
Copy the code

Demo: start a Fibonacci (Fibonacci) sequence

1,1,2,3,5,8,13…

  • Create a fibonacci_test.go file.

  • Write the following code:

package fibonacci

import (
	"testing"
)

func TestFibList(t *testing.T) {
	// var a int = 1
	// var b int = 1

	// var (
	// a int = 1
	// b int = 1
	// )

	a := 1
	b := 1

	for i := 0; i < 5; i++ {
		t.Log("", b)
		tmp := a
		a = b
		b = tmp + a
	}
}
Copy the code
  • Run under terminal:
go test fibonacci_test.go -v
Copy the code

Definition of variable and constant

1. The variable

Variables can be defined in three ways:

  • First, the general declaration one by one:
	var a int = 1
	var b int = 1
Copy the code
  • Second: Unified declaration:
	var (
	  a int = 1
	  b int = 1
	)
Copy the code
  • Third: quick declaration, the compiler will infer the type of the variable from the attached value.
	a := 1
	b := 1
Copy the code

2. The constant

  • Regular assignment:
 const abc = 2
Copy the code
  • Quick setting of continuous constant values:
// Continuous bit constant assignment
const (
	Monday = iota + 1
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
	Sunday
)
Copy the code
  • Quick setting of continuous bit constant values:
// Bit constant assignment
const (
	Readable = 1 << iota
	Writeable
	Executable
)
Copy the code

Basic data types

type grammar
The Boolean bool
character string
The integer Int, int8, int16, int32, int64
Integer without negative sign Uint, UINT8, UINT16, uint32, uint64, uintpTR
floating-point Float32, float64
character Byte (equivalent to uint8)
Unicode or UTF-8 encoding Rune (equivalent to INT32)
The plural form Complex64, complex128

Note: The Go language does not support “implicit casting”, only “explicit casting”. (Implicit type conversions are not even supported between “alias types” and “native types.”)

For example:

	var a int32 = 1
	var b int64

	b = a        // error: implicit type conversion, compiler error error.
	b = int64(a) // Correct: explicit type conversion, successful.
Copy the code

Typical predefined values are as follows:

predefined grammar
The biggest Int64 math.MaxInt64
Minimum Int64 math.MinInt64
Minimum Int32 math.MaxInt32
Minimum Int32 math.MinInt32
The biggest float64 math.MaxFloat64
The biggest float32 math.MaxFloat32
. .

Pointer types

Differences from other programming languages:

  • Pointer operations are not supported.

  • String is a value type whose default initialization value is an empty string, not nil.

For example:

func TestPoint(t *testing.T) {
	a := 1
	aPoint := &a
	// error: Go does not support pointer operations.
	t.Log(a, aPoint)
	t.Logf("%T %T", a, aPoint)
}

func TestString(t *testing.T) {
	var s string
	t.Log("String:" + s + "?")
	t.Log(len(s))

	if s == "" { // String initialization cannot be nil because string initialization defaults to an empty string
		t.Log("S is not initialized.")}}Copy the code

5. Operators

1. Arithmetic operators:

The operator describe
+ add
Reduction of
* take
/ In addition to
% Take more than
a++ The rear since
a– The rear the decrement

Note: There is no pre-increment (++) and decrement (–) in Go.

2. Comparison operator:

The operator describe
= = Determine whether the value“Equal”
! = Determine whether the value“Unequal”
> Determine whether“More than”
< Determine whether“Less than”
> = Determine whetherGreater than or equal to
< = Determine whether“Less than or equal to”

Note: The conditions for comparing == between two arrays? 1. Both arrays have “the same number of elements”. 2. The value of each element in two arrays is equal to the value of each element.

Let’s write a small demo and test it out:

	a := [...]int{1.2.3.4}
	b := [...]int{1.3.4.5}
	c := [...]int{1.2.3.4}
	d := [...]int{1.2.3.4.5}

	t.Log(a == b) // false
	t.Log(a == c) // true

	// t.log (a == d
	t.Log(d)
Copy the code

3. Logical operators:

It’s not too different from any other language, just to mention.

The operator describe
&& AND operator, same astruefortrue, otherwise,false.
\ |
! The NOT (NOT) operator, inversely,trueforfalse.falsefortrue.

4. Bit operators :(new& ^Bitwise clear operator)

The operator describe
& Binary and operations.
\
^ Binary xOR operation.
<< Binary “left shift” operation.
>> Binary “right shift” operation.
& ^ A binary“Zeroing by bit”. Set all the ones on the right to 0. (Operate on the left)

Note: One too many& ^, the bitwise zeroing operator.

Here’s an example:

// Continuous bit constant assignment
const (
	Monday = iota + 1
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
	Sunday
)

// Test zeroed by bit
func TestBitClear(t *testing.T) {
	a := 5 / / 0101
	t.Log("Before bit clearing :", a) / / 0101

	a = a &^ Wednesday / / 5 & ^ 3
	t.Log("After bitwise zeroed out :", a) / / 0100
}
Copy the code

Conditions and cycles

1. If

Differences from other programming languages:

  1. The condition must bebooltype
  2. Variable assignment is supported

Something like this:

	if var declaration; condition {
		/ /...
	}
Copy the code

Here’s a simple example:

	if a := 647; a == 647 {
		t.Log(a)
	}
Copy the code

If you write a request, it looks something like this:

	if v, err := someFunc(); err == nil {
		// No error, success! Do something!
	} else {
		// There is error, failed! Do something!
	}
Copy the code

2. Condition: Switch

Switch differs a little from other major programming languages in that it is more convenient and faster.

  1. The defaultbreakYou don’t have to writebreak. (Use only if you want to run throughfallthroughKeyword, this is very similar to Swift. Note: but I test results gofallthroughThey don’t judge the next onecaseCondition, but directly execute the next onecaseThe code in)
  2. Conditional expressions do not restrict “constants” or “integers”.
  3. A singlecaseMultiple result options are supported, separated by commas.
  4. I don’t have to set itswitchAfter the conditional expression, so with multipleif,elseSame logic.

Here’s an example:

func TestSwitchCondition(t *testing.T) {
	for i := 0; i < 5; i++ {
		switch i {
		case 0.2:
			t.Log("Even")
		case 1.3:
			t.Log("Odd")
		default:
			t.Log("it is not 0-3")}}}func TestSwitchCaseCondition(t *testing.T) {
	for i := 0; i < 5; i++ {
		switch {
		case i%2= =0:
			t.Log(i)
			// fallthrough
		case i%2= =1:
			t.Log(i)
			// fallthrough
		default:
			t.Log("unknown")}}}Copy the code

3. Loop: Go only supports the for keyword.

Here’s an example:

func TestWhileLoop(t *testing.T) {
	/* Mimics the while loop */
	n := 0
	for n < 5 {
		t.Log(n)
		n++
	}

	/ / a for loop
	for n := 0; n < 5; n++ {
		t.Log(n)
	}

	/* infinite loop */
	for {
      / /...}}Copy the code

Arrays and slices

An array of 1.

  • Array declaration:
	var a [3]int // Declare and initialize to the default value 0
	a[0] = 1     // Simple assignment

	b := [3]int{1.2.3}           // declare while initializing
	c := [2] [2]int{{1.2}, {3.4}} // Declare a multidimensional array for initialization
Copy the code
  • Array traversal:
func TestArrayTravel(t *testing.T) {
	arr := [...]int{1.3.4.5}

	for i := 0; i < len(arr); i++ {
		t.Log(arr[i])
	}

	for _, element := range arr {
		t.Log(element)
	}

	for index, element := range arr {
		t.Log(index, element)
	}
}
Copy the code
  • Array interception:
func TestArraySection(t *testing.T) {
	arr := [...]int{1.2.3.4.5}
	arr_sec := arr[1:2]
	t.Log(arr_sec)
}
Copy the code

2. Slice

A slice is a variable length structure. (Sort of like MutableArray in iOS)

  • Section declaration:
	var s0 []int       / / declare
	s0 = append(s0, 1) / / append

	s := []int{}            / / declare
	s1 := []int{1.2.3}    // Declare and provide initialization values
	s2 := make([]int.2.4) // Declare and provide the number of initializations: 2, Max Maximum number of elements: 4.
	/* Syntax: make([]type, len, cap) where len elements are initialized to the default value 0, uninitialized elements are inaccessible. * /
Copy the code

1. Quick declaration syntax: make([]type, len, cap) where the first len elements are initialized to the default value 0, uninitialized elements are not accessible. (This is a crash prone point and cannot be crossed.)

2. Append element syntax: s = append(s, Element) where S stands for slice and element stands for append.

  • Slice simple use: directly on demo,
func TestSliceInit(t *testing.T) {
	var s0 []int
	t.Log(len(s0), cap(s0))

	s0 = append(s0, 1)
	t.Log(len(s0), cap(s0))

	s1 := []int{1.2.3.4} // Initialize slices quickly
	t.Log(len(s1), cap(s1))

	s2 := make([]int.3.5) // Initialize three. Max number is 5
	t.Log(len(s2), cap(s2))

	t.Log(s2[0], s2[1], s2[2])

	s2 = append(s2, 1) // Add elements
	t.Log(s2[0], s2[1], s2[2], s2[3])
	// t.Log(s2[0], s2[1], s2[2], s2[3], s2[4])
}
Copy the code
  • Principle of slicing: The shared storage structure of slicing. When slice the number of elementslenMore thancap, will proceed2Times the capacity.

Map (Key: Value)

1.Map basic operations:

  • There are three ways to initialize a Map:
	/* The first type of initialization has an initial value */
	m1 := map[string]int{"Key1": 1."Key2": 2."Key3": 3}
	t.Log(m1)
	t.Logf("len m1 = %d".len(m1))

	/* Second initialization method: no initial value */
	m2 := map[string]int{}
	m2["Key"] = 16
	t.Logf("len m2 = %d".len(m2))

	/* Third initialization: initialize cap size (Max capacity), but len is still 0. Map, unlike arrays, has a default value of 0, so len is still 0
	m3 := make(map[string]int.10)
	t.Logf("len m3 = %d".len(m3))
Copy the code
  • Access to Map elements:

If the Map accessed does not have a specified Key, 0 is returned by default. Therefore, in Go, the existence of a Key cannot be determined by whether the Value is null.

If you want to check whether Value exists, use the following methods:

if value, ok := map[key]; ok {
  / / a value
} else {
  / / no value
}
Copy the code

The Demo:

func TestAccessNotExistingKey(t *testing.T) {
	m1 := map[int]int{} // Initialize an empty map
	t.Log(m1[1])        // Access a Key randomly? The printed result is 0

	m1[2] = 0    // Set a Key(2) and Value(0).
	t.Log(m1[2]) // Print 0 again

	if value, ok := m1[3]; ok { // var v = m1[3], ok is the bool of the expression
		t.Logf("Key 3 's value is %d", value)
	} else {
		t.Log("Key 3 is not existing.")}}Copy the code
  • Map traversal:

This is similar to the for-range array except that “array returns index, Map returns Key”.

func TestTravelMap(t *testing.T) {
	map1 := map[string]int{"Key1": 1."Key2": 2."Key3": 3}
	for key, value := range map1 {
		t.Log(key, value)
	}
}
Copy the code

2.Map and Factory mode

  1. The Map ofValueIt could be a method.
  2. With the GoDock typeTogether with the interface approach, it is easy to implement the factory pattern of a single method object.
func TestMapWithFunValue(t *testing.T) {
	m := map[int]func(op int) int{}
	m[1] = func(op int) int { return op }
	m[2] = func(op int) int { return op * op }
	m[3] = func(op int) int { return op * op * op }
	t.Log(m[1] (2), m[2] (2), m[3] (3))}Copy the code

3. Implement Set in Go language

Go has no implementation of Set, but can be implemented through map[type]bool.

  1. Uniqueness of elements
  2. Basic operations (add element, check element existence, delete element, number of elements)
func TestMapForSet(t *testing.T) {
	mySet := map[int]bool{} // Initialize the map
	mySet[1] = true         // Set key and value
	n := 3
	if mySet[n] {
		t.Logf("%d is existing", n)
	} else {
		t.Logf("%d is not existing", n)
	}

	mySet[3] = true // Set Key and value
	t.Log(len(mySet))

	delete(mySet, 1) // Delete the map whose Key is 1
	t.Log(len(mySet))
}
Copy the code

Ix. String

Differences from other programming languages:

  • A string is a “value type,” not a reference or pointer type. Therefore, when initialized by default, it will be an empty string. (Instead of nil)

  • String is a read-only byte slice, and len returns the number of bytes in the string.

  • A String byte array can hold any data.

Such as:

s = "\xE4\xB8\xA5" // Can store any binary data
Copy the code
  • withlenSo what we get is thetabyteNumber, not character number.

Q: How is Unicode related to UTF8? A: Unicode is a character set. Utf-8 is a storage implementation of Unicode. (Rules for converting to byte sequences)

Here’s an example:

coding storage
character “In”
Unicode 0x4E2D
UTF-8 0xE4B8AD
string/[]byte [0xE4, 0xB8, 0xAD]
  • Use Go language supportstrings,strconvLibrary:

First, import strings and strconv libraries:

import (
	"strconv"
	"strings"
)
Copy the code

String segmentation and splicing demo:

// Test the strings library
func TestStringFunc(t *testing.T) {
	s := "A,B,C"
	parts := strings.Split(s, ",") // The string is separated by ","
	for _, part := range parts {
		t.Log(part)
	}
	t.Log(strings.Join(parts, "-")) // Press "-" to concatenate the string
}
Copy the code

String transformation demo:

// Test the strconv library
func TestConv(t *testing.T) {
	s := strconv.Itoa(10) / / Int string
	t.Log("str" + s)

	if value, err := strconv.Atoi("10"); err == nil {
		t.Log(10 + value)
	} else {
		t.Log("Conversion failed!")}// t.log (10 + strconv.atoi ("10")) // string to Int, compiler error
}
Copy the code

X. Functions: first-class citizens (can be used as variables, parameters, return values)

Differences from other programming languages:

  • A function can have multiple return values.

  • All parameters are passed by value, not by reference. Slice, map, and channel have the illusion of passing references. Slice, map, and channel are themselves structures that contain Pointers to the next slice, map, and channel. So the slice, map, and channel we pass into the function as arguments are actually copied, but the other objects that operate on themselves are still the memory addresses of the original Slice, map, and channel.

This may be a bit convoluted, but let’s look at how slice works. (PS: Refer to “Article 7” section principle)

  • Functions can be values of “variables”.

  • Functions can be used as “arguments” and “return values”.

Key points: Functional Programming (Go)

Because in Go, functions can be variables, parameters, return values. As a result, programming conventions are somewhat different from those of other programming languages. Developers need to get used to it.

Practical tips

  1. Supports variable length arguments for functions

Syntax: [Parameter name]… [Parameter type]

PS: The number of parameters is not specified, but the parameter type must be specified.

For example, if we want to write a summation function, we can write it like this:

// Sum function
func sum(ops ...int) int {
	s := 0
	for _, op := range ops {
		s += op
	}
	return s
}
Copy the code
  1. Supports delayed execution of functions, mostly used to release resources (unlock)

Here’s an example:

// mimic the function that frees resources
func Clear(a) {
	fmt.Println("Clear resources.")}// Test function delayed execution: mostly used to release resources
func TestDefer(t *testing.T) {
	defer func(a) {
		// Release some resources (locks)
		Clear()
	}()
	fmt.Println("Started")
	panic("Fatal error") // Panic: The program is interrupted and defer will still execute
}
Copy the code

Finally, this series is summed up and completed in practice under the technical sharing of Teacher CAI Chao. Thank you for your technical sharing.

PS: Attached, sharing link: “Go Language from entry to actual combat” wish you all success in your study and work smoothly. Thank you very much!