Go study notes

Go development

1, Basic knowledge

1.1 basic structure

(1) The suffix of the go file is. Go

(2)package main

Indicates that the package where the hello.go file is located is main. In go, each file must belong to a package.

(3)import "fmt"

Represents the introduction of a package. You can use the functions in the fmt package

(4)func main(){

}

func is a keyword that represents a function.

Main is the function name. It is a main function, which is the entry of the program

*In go language, you must use variables to create variables, otherwise an error will be reported.

*The first capital letter of the identifier indicates that the variable is public, and the first lowercase letter indicates that the variable is private and can only be used in the current package

1.2 escape character

package main

import "_fmt"  //_ Indicates that the package will not be used for the time being
func main( )  {
   fmt.Println("tom\tjack") //Tab for alignment

   fmt.Println("hello\nword") //Newline character

   fmt.Println("D:\\Go tool\\GoLand 2021.1.3\\bin") // "\ \" output a\

   fmt.Println("Tianlong Babu snow mountain flying fox\r Zhang") //Overwrite all content
}

1.3 code specification

1) Line comment

//Note content

2) Block annotation

/*

Note Content

*/(a block note cannot be nested inside a block note)

3) Code to achieve indentation, you can use the shift+tab key, or use gofmt format

1.4 basic DOS operation

1) dir view the contents of the current directory file

2) cd /d f: switch other disks, for example, from disk d to disk f

3) cd d: \ test100 switch from the current disk to the current disk file package

4) cd... Back to parent directory

5) cd \ back to top level directory

6) md create an empty directory

7) rd delete empty directory

8) rd /q/s delete directory (regardless of content)

9) rd /s delete directory with query

10) echo content > absolute directory path of the file you want to create (d: \ test100\abc100\hello.txt)

11)copy specifies the directory path of the file to be copied (abc.txt d: \ test100)

12)move file name the path of the file directory to be moved (you can add the file name after the path if you want to change it)

13) del *.txt delete all files of this type

14) cls clear screen

15) Exit exit

2, Go language knowledge

2.1. Golang variable

2.1.1 demonstration of creating variable code

package main

import "fmt"
var(
    i1 = 100
    name2 = "joke"
    i3 = 1000
   ) //Create global variable

func main() {
	var i int;   //When specifying a variable type, create a variable format
	i = 100
	fmt.Println("i=",i)
    
    n := "tom"  //When var is omitted, add:=
    fmt.Println("name=",n)
    
    var n1, n2, n3 int //Create multiple variables
    fmt.Println(n1,n2,n3)
    
    var a, name, b = 100,"tom",88 //Create multiple variables at one time, where are one-to-one correspondence
    fmt.Println(a,name,b)
    
    j, na, k := 100,"tom",88 //Omit var
    fmt.Println(j,na,k)
    
    fmt.Println(i1,name2,i3)
}

2.1.2 data type

2.1.2.1

*byte can only store one character. There is no special char type in go

2.1.2.2 integer type

typeSign or notRangeremarks
inthave-63rd power of 2 ~ 63rd power of 2 - 1
uintnothing64th power of 0 ~ 2 - 1
runehave-The 31st power of 2 ~ the 31st power of 2 - 1Equivalent to int32, representing a Unicode code
bytenothing0~255Select byte when you want to store characters

**When using integer variables in Golang program, the principle of keeping small but not large shall be observed, that is, the data type with small occupation space shall be adopted when ensuring the normal operation of the program.

2.1.2.3 floating point

typeOccupied spaceRange
Single precision (float)4 bytes-3.403E38~3.403E38
double8 bytes-1.798E308~1.798E308

2.1.2.4 character type

(1) Strings in go are spliced by characters

(2)

package main

import "fmt"
func main() {
	var n1 byte = 'a'
	var n2 byte = '0'
	
	 fmt.Println("n1",n1)
	 fmt.Println("n2",n2)   //Only code values can be output
	 fmt.Printf("n2 = %n2",n2)//Formatted output can output characters
    
     //If the ASCII range is exceeded
     var n3 int = 'north'
     fmt.Printf("n3 = %n3",n3)  //If the variable is assigned a number and then output according to the format, the corresponding character will be output.
    
     
}

2.1.2.5 boolean type

(1) Boolean type values can only be true and false

2.1.2.6 string type

package main

import "fmt"
func main() {
	//Basic use
    var adress string = "adfadsf sdafdasf"
    fmt.Println(adress)
}

(1) The string in go is immutable

(2) When creating a string variable, you can use

Back quotation marks ` `, you can output the source code. Double quotation marks "" will recognize the special characters in quotation marks

(3) When a splicing operation is very long, it can be written separately, and the plus sign must be on it

var str = "hello" +
          "world" +
          "hahaha"

2.1.2.6 data type conversion

 var i int32 = 100
 var n1 float32 = float32(i)
 //The rest are similar to this conversion structure. Note that the data type of i after conversion has not changed

 //Data basic type conversion string
 //Method 1: use fmt.Sprintf
 var num1 int = 99
 var str string
 str = fmt.Sprintf("%d",num1)
 fmt.Printf("str type %T str = %v",str,str)
 
 //Method 2: use strconv function. See the Chinese document of go standard library for details
 str = strconv.FormatFloat(num1,'f',10,64) //Note: 'f' format 10 means that 10 decimal places are reserved, and 64 means that the decimal is float64
 
 //Convert string type to data base type
 var str string = "true"
 var b bool

 b , _ = strconv.ParseBool(str)//Because this function returns two values, the second value is ignored, means ignored

Note: when converting a string to a basic type, ensure that it can be converted to valid data, otherwise Golang will directly convert it to 0

2.2 pointer

package main
import (
    "fmt"
)
func main(){
    
    var num int = 100
    //Create go pointer
    var ptr *int = &num
    
    var num2 int = *ptr
    
    fmt.Printf(num," ",ptr," ",num2)
}

2.3 value type and reference type

2.3.1 value type

Basic data types include int series, float series, bool, string, array and struct

2.3.2 reference type

Pointer, slice slice, map, pipe chan, interface, etc

2.4 operator and terminal input

Note: + + and – can only be used independently, for example

package main
import (
    "fmt"
)
func main(){
    var name string
    var i int = 8
    var a int
    //a = i + +, which is the wrong way to write
    i++
    a = i   //i should first implement + + and then assign a value to a

    //++i or -- i this is wrong. There is no front -- or front in go++
    
    
	//Input from the terminal, mode 1:
    fmt.Scanln(&name)//Here is to pass the address of name to the function. You can enter the value of name from the terminal
    fmt.Printf("name is %v",name)
    
    //Mode 2:
    fmt.Scanf("%s",&name)//Note that multiple entries need to be aligned one by one
}

2.5 process control

2.5.1 if statement

    //Mode 1:
	var age int
	var age1 int
	fmt.Println("Please enter age")
	fmt.Scanln(&age)

	if age < 0 {
		fmt.Println("You're a fake")
	}
 
	//Mode 2:
	if age1 = 20; age1 > 18 {
		fmt.Println("You're an adult, boy")
	}
	//In go, add {} no matter how many statements are in the if statement
	if age > 18 {
    	fmt.Println("You're an adult, boy")
	}else {                              //else here must be written on this line, or an error will be reported
    	fmt.Println("You're still a minor")
	}

2.5.2 switch statement

switch expression {
    case Expression 1, expression 2.... :
    	Statement block
    case Expression 1, expression 2.... :
    	Statement block
    fallthrough//After executing this statement, you can also execute the next statement
    case Expression 1, expression 2.... :
    	Statement block
    
    
    .
    .
    .
    default:
    	Statement block
    //In the go language, the switch statement does not have a break, but has a break by default
    //switch can be followed by a constant or a function return value
    //switch can not be followed by an expression
    /*For example: switch{
    			case age == 10:
    			Statement block
    }
    */
    
}

2.5.3 circular statements

//Mode 1:
for i = 1; i < 10; i++ {
	Statement block
}
//Mode 2:
var j  =  1
for j < 10 {
    j++
}

for{	
    Statement block
    break
}//The for loop does not need to write loop conditions, but needs to add break to terminate the loop

//for range string traversal or array traversal
str := "hello"
for index, val := range str{
    fmt.Println("index=%d, val=%c \n",index, val)
}//If there is Chinese in the string, Chinese garbled code will appear in traditional traversal, which can be converted into slice STR2: = [] run (STR)

2.6 jump control statement

2.6.1 break

1) Introductory case

package main
import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	//To generate a random number, you also need a rand to set a seed
	//time.Now().Unix(): returns the number of seconds from 0 hour, 0 minute, 0 second at 1970:01:01 to the present
	//rand.Seed(time.Now().Unix())
	//How to randomly generate integers from 1 to 100
	//n := rand.Intn(100) + 1
	//fmt.Println(n)
	var count int = 0
	for {
		rand.Seed(time.Now().UnixNano())
		n := rand.Intn(100) + 1
		count++
		fmt.Println("n=",n)
		if(n == 99){
			break
		}
	}

	fmt.Println("A total of 99 were generated",count)
}

2) Using break in a nested loop, you can specify which loop to jump out of through the tag.

lable1:
for i := 0; i < 10; i++ {
    if i == 2 {
        break lable1:
    }
}

2.6.2 continue

1) continue can also skip that loop through the tag

lable1:
for i := 0; i < 10; i++ {
    if i == 2 {
        continue lable1:
    }
    fmt.Println(i)
}

2.6.3 goto and return

2.7 function

2.7.1 create function

func Function name(Parameter name parameter data type) (Return value data type) {//If there is only one return value, you can not add ()
    Execute statement block...
    return Return value
}

2.7.2 use of package

1) When referring to functions or variables in the package, you need to capitalize the variable name or function name

2) When packaging files, the package name is usually the same as the folder

3) When importing a package, src starts. Instead of replacing src, the compiler will automatically import it from under src

4) You can alias the package, but the original package name cannot be used

package main
import (
	"fmt"
    util"go_code/breakDmeo/util"
)

5) You cannot have the same global variable name or function name under the same package

2.7.3 function details

1) In go, a function is also a data type and can be assigned to a variable, which is also a variable of this function type. This variable allows you to call a function

package main
import "fmt"

func getSum(a int, b int) int {
    return a + b
}
func main() {
     
    n1 := getSum
    
    n2 := n1(10,40) //Equivalent to getSum(10,40)
}

2) Since the function is a data type, in Go, the function can be used as a formal parameter and called

package main
import "fmt"

func getSum(a int, b int) int {
    return a + b
}

func myFun(funvar func(int,int)int,num1 int, num2 int) {
    return funvar(num1,num2)
}
func main() {
     
    n1 := getSum
    
    n2 := n1(10,40)
}

3) You can alias data types

package main
import "fmt"


type myType func(int,int)int //In this case, myType is func(int,int)int type

func myFun(funvar myType,n1 int, n2 int) {
    return funvar(num1,num2)
}

func getSum(a int, b int) int {
    return a + b
}

func main() {
    res3 := myFun(getSum,500,600)
    fmt.Println(res3)
}

4) Support naming return values

package main
import "fmt"

func getSumAndSub (a int, b int) (sum int,sub int {
    sum = a + b
    sub = a - b
    return
}
func main() {
	var sum1 int
	var sub1 int
	sum1,sub1 = getSumAndSub(12,56)
}

5) Go supports variable parameters

//0 to more than one formal parameter is supported
func sum(args... int) sum int{
 	
 }
 //One to more formal parameters are supported. At this time, args is a slice, which is equivalent to an array
func sum1(n1 int,args... int) sum int{
 	
 }

2.7.4 init function

1) The inti function usually runs before the main function to complete some initialization:

package utils
import "fmt"
var Age int
var Name string


func init(){
    fmt.Println("utils Wrapped init().....")
}
2)package main
import ("fmt"
        "go_code/charpter04/utils"
       )

var i int = test()

func test() int {
    fmt.Println("test() Medium test().....")
}

func init() {
    fmt.Println("init Medium init.......")
}

func main() {
    fmt.Println("main()......i = ",i)
    fmt.Println("Age = ", Age, "Name = ", Name)
}

2) If a file includes global variable definition, inti function and main function, the general execution order is global variable - "inti function -" main function "

2.7.5 anonymous functions

1) Called directly when defining anonymous functions, but only once

res1 := func (n1 int, n2 int)int {
	return n1 + n2
}(10,20)

2) Assign the anonymous function func (i int, j int) int to a, and then the function call can be completed through a, but a is not a function name (it can be used to write a function and call)

a := func(i int,j int) int {
	return i + j
}

res := a(10 , 20)

3) Global anonymous function

var {
	fun = func(i int, j int) int {
	return i + j
	}
}

func main() {
	res := fun(10,20)
}

2.7.6 closure

1) A closure is a combination of a function and its associated reference environment

2) Case presentation:

func AddUpper() func(int) int {
	var n int = 10                //The following are closures
	return func(x  int) int {
	n = n + x
	return n
	}
}                                 //above

func main() {
    f := AddUpper()
    fmt.Println(f(1))
    fmt.Println(f(2)) //Every call n is not initialized, but accumulated
}

3)

package main

import (
	"fmt"
	"strings"
)

func makeSuffix(suffix string) func (string) string {

	return func (name string) string {
		if !strings.HasSuffix(name, suffix) {
			return name + suffix
		}

		return name
	}
}

func main() {

	f := makeSuffix(".jpg")

	fmt.Println("The format after file processing is:" , f("winter"))
}

2.7.7 defer of function

1)

package main

import 
	"fmt"

func sum(i int, j int) int {
    defer fmt.Println("000")  //When the defer statement is executed, it is not executed temporarily and pushed into a separate stack. Execution sequence 3
    defer fmt.Println("111") //After the function is executed, all defer statements will be executed in the order of first in then out. Execution order 2
    
    tes := i + j
    fmt.Println("tes",tes) //Execution sequence 1
    return tes
}

func main() {
    res := sum(10 , 20)
    fmt.Println("res ",res) //Execution sequence 4
}

2) The advantage of defer is that it can release the resources created by the function in time

2.7.8 common system functions of string

1) Statistics string length

len(str), no need to import package

2) String traversal, and deal with Chinese garbled code at the same time

str2 := "hello world"
str3 := []rune(str2)   //Convert to slice
for i := 0; i < len(str3); i++{
    fmt.Printf("character=%C\n", r[i])
}

3) String to integer and integer to string

//This function needs to import "strconv"
n, err := strconv.Atoi("123")//String to integer
if err != nil {
    fmt.Println("Conversion error")
}else{
    fmt.Println("Conversion succeeded",n)
}

str := strconv.Itoa(123456)  //Integer to string

4) String to [] byte: var bytes = []byte("hello go")

Convert to [] byte convert to string

 var bytes = []byte("hello go") //You can get the code of hello go

str := string([]byte{97,98,99}) //The characters abc corresponding to 97, 98 and 99 can be obtained

5) Hexadecimal to hexadecimal: str = strconv.Formatlnt(132,2), where the returned time string

6) Find whether the substring is in the specified string: strings.Contains("seafood", "foo") / / true

//You need to introduce "strings"
strings.Contains("seafood","foo") //Return true

7) Count one string and several specified strings

num := strings.Cont("see","e") //Return 2

8) Compare regardless of case

b := strings.EqualFold("abc","ABC") //Return true
//"abc" == "ABC" false "= =" is case sensitive

9) Returns the first occurrence and last occurrence of a substring in a string

index1 := strings.Index("dafdas","f") //Returns 3, or - 1 if not
index2 := strings.LastIndex("dafdas","a") //Return 5

10) Replaces the specified substring with another substring

str := strings.Replace("go go beijing","go","hello",1)
//Get hello go beijing
//Where 1 refers to replacing several. If all of them are replaced, write - 1. At the same time, "go / / Beijing" can be a variable, for example: STR2: = "go Beijing"
//STR: = strings. Replace (str2, "go", "hello", 1), where str2 itself has not changed

11) According to a certain character, a string is converted into a character array for segmentation identification

strArr := strings.Split("hello,world",",")
//Get strArr=[hello world]

12) Case conversion

str = strings.ToLower("GO")
str = strings.ToUpper("go")

13) Remove the left and right spaces from the string: string. Trimspace ("to go")

Remove the specified characters around the string: strings.Trim("! hello!", "!")

Remove the specified character from the left of the string: strings.TrimLeft("")

Remove the specified character from the right side of the string: strings. Trimright ("")

Judge whether the string starts with a character: strings.HasPrefix("adfasdf", "a")

Judge whether the string ends with a character: strings.HasSuffix("adfasdf", "f")

2.7.9 date and time correlation function

//"time" needs to be introduced
//1) Get current function
now := time.Now()
//2) Get additional date information
fmt.Printf("year = %v\n",now.Year())
fmt.Printf("month = %v\n",now.Month())
fmt.Printf("day = %v\n",now.Day())
fmt.Printf("hour = %v\n",now.Hour())
fmt.Printf("minute = %v\n",now.Minute())
fmt.Printf("second = %v\n",now.Second())
//3) Format date function
fmt.Printf(now.Format("2006-01-02 15:04:05")) //You can get the current time, but the number is fixed and cannot be changed
//4) Time sleep function time.Sleep()
//Time.second time.hour time.minute time.milliseconds time.microseconds

2.7.10 built in functions

Note: functions that can be used directly without citing packages, for example: 1) new

num2 := new(int)
//num2 is of type * int, i.e. pointer

2)len(str)

3) make: mainly used to allocate memory

2.8 exception handling

1) Quick start

package main

import "fmt"

func test() {
    //Use defer + recover to catch and handle exceptions
	defer func() {
		err := recover() // recove() is a built-in function that can catch exceptions
		if err != nil {	 // Description exception caught
			fmt.Println("err =", err)
		}
	}()
	num1 := 100
	num2 := 0
	res := num1 / num2
	fmt.Println("res=", res)
}

func main() {
	test()
	fmt.Println("main.....")
}

2) Custom error

package main

import ("fmt"
        "errors"
       )

func readConf(name string) (err error) {
    //If the input file name is incorrect, a custom error is returned
    if name == "config.ini" {
        return nil
    } else {
        return errors.New("Error reading file..")
    }
}

func test() {
    err := readConf("config.ini")
    if err != nil {
        //If there is an error reading the file, output the error and terminate the program
        panic(err)
    }
    
    fmt.Println("Continue with the program")
}

func main() {
	
}

2.9 array

2.9.1 one dimensional array

1) Traversal of array: for range

array := [...]int{1,2,3}
for index,value := range array{
    fmt.Println(value)
}

① The first index returns the array index

② The second value is the value

③ Only local variables in the for loop

④ You can use "_" to omit the subscript value

⑤ index and value can be customized variable names

2) Precautions

① var arr []int where arr is slice slice slice

② After the array is created, if there is no assignment, there is a default value

1. Numeric type (integer, floating point number, etc.) = > 0

2. String = > ""

3. Boolean type = > false

2.9.2 two dimensional array

Traversal:

1) Double for loop

2) For range traverses a two-dimensional array

for i, v := range arr {
    for j, v2 := range v {
        fmt.Println("arr[%v][%v] = %t", i, j, v2)
    }
}

2.10 slicing

2.10.1 basic introduction

1) Slice is a reference to array, so slice is a reference type. When passing, follow the mechanism of reference passing

2) The length of slices can be changed, which is equivalent to a dynamically changing array

3) Demo:

package main

import "fmt"

func main() {
    var intArr [5]int = [...]int{1,22,5,5,6}
    //Define a slice
    //slice := intArr[1:3]
    //intArr[1:3] indicates that slice refers to the array intArr
    //The starting subscript of the referenced intArr array is 1 and the last subscript is 3 (excluding 3)
    slice := intArr[1:3]
    
    fmt.Println("slice element =",slice) // 22,33
    fmt.Println("slice Number of elements =",len(slice))//2
    fmt.Println("slice capacity =",cap(slice))//The capacity of slices can change dynamically
}

2.10.2 slice memory layout

Note: 1.slice is a reference type

2.slice is equivalent to a structure from the bottom layer:

type slice struct{

ptr *int / / the address where the data is stored

Len int / / number of slice elements

Capacity of cap int //slice

}

2.10.3 use of slices

1) Define a slice, and then let the slice reference a created array, as in the above example

2) Create slices with make

func main() {
	var slice []int = make([]int,4,10) //Data type, len, cap capacity, the array corresponding to a slice created by make is invisible, and the data can only be accessed through slice
	slice[0] = 100
	slice[2] = 200
}

3)

func main() {
    var slice []string = []string{"jose","joe","jojo"}
}

4) Distinction

① The difference between mode 1 and mode 2 is that mode 1 always refers to a pre-existing array as visible; In mode 2, when creating slices through make, an array will also be created. The slices are maintained at the bottom level and are invisible

5) Note:

① Slice: = arr [: 3] / / the default is 0-3 (excluding 3), and [0:] the default is 0-len(arr)

② Slicing can continue slicing

slice2 := slice[0:1]

③ Append element

var slice1 []int = []int{100,200,300}

Slice2 = append (slice1400500600) / / here, append creates a new memory, but slice1 does not change

slice3 = append(slice3,slice2...)

④ Copy of slice

copy(pare1,pare2) are both slice types. They are spatially independent and do not interfere with each other

⑤ string and slice

(1) The value of string array is immutable, but it can be modified by converting string to [] byte slice first and converting it to string array

str := "hello"
arr1 := []byte(str)
arr1[0] = z
str = string(arr1)  //Although this method can change the string array value, it is not allowed if there is Chinese in the string

//If string has Chinese

arr2 := []rune(str)
arr2[0] = "cover"
str = string(arr2)

2.10.4 traversal of slices

package main
import "fmt"

func main() {
    //Regular for loop traversal
    var arr [5]int = [...]int{1,2,3,4,5}
    slice := arr[1:4]
    
    for i:= 1; i < len(slice); i++{
        fmt.Println("slice[%v]=%v", i, slice[i])
	}
    
    //Traversal using the for range method
    for i, v:= range slice {
        fmt.Println(i," ",v)
    }
}

2.11 map

2.11.1 basic grammar

var variable name map [key] ValueType

//Example: var a map[string]string
//var a map[string]map[string]string

Note: the declaration will not allocate memory. make is required for initialization, and can be assigned and used only after allocation

package main
import "fmt"

func main() {
    //Mode 1
    var a map[string]string
    a = make(map[string]string,10) //make allocate space
    a["no1"] = "joke"
    a["no2"] = "sandy"
    fmt.Println(a)
    
    //Mode II
    b := make(map[string]string)
    b["no1"] = "hehe"
    fmt.Println(b)
    
    //Mode III
    c = map[string][string]{
        "no1" : "wj",
        "no2" : "wjj"
    }
    setStu := make(map[string]map[string]string)
    setStu["stu1"] = make(map[string]string,3)
    
    setStu["stu1"]["name"] = "tome"
    setStu["stu1"]["sex"] = "man"
    setStu["stu1"]["age"] = "16"
    
    fmt.Println(setStu)
    fmt.Println(setStu["stu1"])
    fmt.Println(setStu["stu1"]["name"])
    //The key of map cannot be repeated. If it is repeated, the last one shall prevail
    //The map is disordered
}

2.11.2 addition, deletion, modification and query of map

package main
import "fmt"

func main() {
    var a map[string]string
    a = make(map[string]string,10)
    a["no1"] = "joke"
    a["no2"] = "sandy"
    fmt.Println(a)
    
    //change
    //key already exists
    a["no1"] = "wj"
    fmt.Println(a)
    
    //delete
    //When the specified key does not exist, it is neither deleted nor reported as an error
    //If you want to delete all key s at once, you can delete them one by one, or use map = make (...) to make a new space, so that the original space becomes garbage and is recycled by gc - "a = make(map[string]string)
    delete(a,"no1")
    
    //lookup
    val,ok := a["no1"]
    if ok{
        fmt.Println("Found it")
    }else{
        fmt.Println("No")
    }
    
}

2.11.3 traversal of map

package main
import "fmt"

func main() {
    var a map[string]string
    a = make(map[string]string,10)
    a["no1"] = "joke"
    a["no2"] = "sandy"
    a["no3"] = "bj"
    fmt.Println(a)
    
    for i,v := range a {
        fmt.Printf("i=%v v=%v\n",i,v)
    }
    
    setStu := make(map[string]map[string]string)
    setStu["stu1"] = make(map[string]string,3)
    
    setStu["stu1"]["name"] = "tome"
    setStu["stu1"]["sex"] = "man"
    setStu["stu1"]["age"] = "16"
    
    for k1, v1 := range setStu {
        fmt.Println("k1=",k1)
        for k2, v2 := range v1 {
             fmt.Printf("\t k2=%v v2=%v",k2,v2)
        }
        fmt.Println()
    }
}
    

2.11.4 map slice

package main
import "fmt"

func main() {
    var monster = []map[string]string
    monster = make(map[string]string, 2)
    if monster[0] == nil {
        monster[0] = make(map[string]string, 2)
        moster[0]["name"] = ["greeny "]
        moster[0]["age"] = ["600"]
    }
    if monster[1] == nil {
        monster[0] = make(map[string]string, 2)
        moster[0]["name"] = ["li Qingfeng"]
        moster[0]["age"] = ["700"]
    }
    
    //Dynamic increase
    newMonster := map[string]string{
        "name" : "Lao Liu",
        "age"  : "600",
    }
    monster = append(monster,newMonster)
}

2.11.5 sorting

package main
import (
    "fmt"
    "sort"
       )
func main() {
    map1 := make(map[int]int,10)
    map1[1] = 13
    map1[7] = 12
    map1[6] = 14
    map1[3] = 122
    map1[2] = 1111
    
    //First put the key of the map into the slice
    //Sort slices
    //Traverse the slice, and then output the map value according to the key
    
    var key []int
    for k,_ := range map1 {
        keys = append(keys,k)
    }
    
    sort.Ins(keys)
    fmt.Println(keys)
    
    for _, k := range keys{
        fmt.Println(map1[k])
    }
}

2.11.6 use details

1) Map is a reference type. A function accepts a map. After modification, the value of the original map will also be changed

2) After the capacity of the map is reached, adding elements to the map will automatically expand the capacity without panic, which can grow dynamically

3) The value of a map also often uses the struct type

2.12 struct structure

2.12.1 quick start

package main
import "fmt"

//The structure name is public in uppercase and private in lowercase
//If the pointer, slice and map are declared in the structure, the zero value is nil, and make is required to allocate space
type Cat struct {
    Name string
    Age int
    
}

func main() {
    var cat1 Cat
    cat1.Name = "blank"
    cat1.Age = 16
    
    var c4 Cat = Cat{"fadsf" , 16}
    //Create a pointer
    var c2 *Cat = new Cat)
    //Normally, it is written as (* c2). Name = "fadsf"
    c2.Name = "dsfads" //The compiler automatically switches to * c2 at the bottom
    fmt.Println(*c3)
    
    var c3 *Cat = &Cat{} //var c3 *Cat = &Cat{"fadsf" , 16}
    c3.Name = "fadsdaf"  //The compiler automatically switches to * c2 at the bottom
    fmt.Println(*c3)
}

2.12.2 use details

1) The attribute memory in the structure is distributed continuously (the address of the pointer is continuous, but the space pointed to is not necessarily continuous)

2) When two structures are converted to each other, their types and member variables should be the same

3) The structure is redefined by type (equivalent to taking an alias). golang considers it a new data type and can be forcibly converted

stu = Studnet(stu1)

2.12.3 method

1) Method declaration and invocation

type A struct {
	Num int
}

func (a A)test() {
	fmt.Println(a.Num)
}

🥰 Func (A) test() {} indicates that there is A play method for structure A, which is called test

🥰 (a) the test method is bound to type A

give an example:

package main
import "fmt"

type Person struct {
    Name string
}

func (p Person) test() {
    fmt.Println("test() name",p.Name)
}

func main() {
    var p Person
    p.Name = "zhangsna"
    p.test() //The test() method can only be called by a Person object
    (&p).test()//The test function will also be called, and P will also be copied in the test function, that is, p.test() = (& P). Test(). If you change the value with & P. test(), but the external P remains unchanged
    /*If there is func (p *Person) test(){
    fmt.Println("test() name",p.Name)
    } You can change the value of main function p
    But p.test() & still works. Test()
    */
}

😴

func (a A)test() {
	fmt.Println(a.Num)
}
//Where A can be A structure or other data types
//To call this method, you need a variable of the corresponding data type

2.12.4 factory mode

Note: the initial letter of the declared structure in the current package is lowercase, and other packages are required. For example, if an instance of this package is created in the main package, the factory mode needs to be introduced.

example:

package main

import (
	"fmt"
	"go_code/factory/model"
)

func main() {
	
	var stu = model.NewStudent("wj",88)
	fmt.Println(stu)
}  

package model:

package model

type student struct {
	Name string
	Age int
}

//Because the student is lowercase, you can only use factory mode if you want to use it in other packages
 func NewStudent(n string, s int) *student{
	 return &student{      //Returns a pointer, that is, this space can be used
		 Name : n,
		 Age : s,
	 }
 }

🔔 Similarly, if there are lowercase member variables in the structure, you also need to provide a method

example:

package model

type student struct {
	Name string
	age int
}

func (s *student) Getage() int {  //How to get lowercase variables
    return s.age
}

2.13 object oriented

2.13.1 quick start

package main
import(
	"fmt"
)

type Account struct {
	AccountNo string
	Pwd string
	Balance float64
}

//deposit
func (account *Account) Deposite(money float64, pwd string) {

	if pwd != account.Pwd {
		fmt.Println("The password you entered is incorrect~~")
		return
	}

	if money <= 0|| money >= account.Balance {
		fmt.Println("The deposit amount you entered is incorrect~~")
	    return
	}

	account.Balance -= money
	fmt.Println("withdraw money ok~~")
}

func (account *Account) Query(pwd string) {

	if pwd != account.Pwd {
		fmt.Println("Password error~~~")
	}

	fmt.Println("Account balance:",account.Balance)
}

func main() {
	account := Account{
		AccountNo : "sadfasd",
		Balance : 1000.6,
		Pwd : "12345",
	}

	account.Query("12345")
}

2.13.2 packaging

1) Hide details

2) The data can be verified to ensure safety and rationality

3) Encapsulates the initial lowercase of the attribute variable in the structure

4) Through the method, the package realizes encapsulation

5) Assign a value to the attribute judgment through an capitalized Set method

func (var Structure class name) Setxxx(){
    
}

6) Get its properties through an uppercase get method

func (var Structure class name) Getxxx(){
    
}

7) There is no special emphasis on encapsulation in Golang

Quick case

package model
import(
	"fmt"
)

type person struct {
	Name string             //Exposed property Name
	sex string				//To use the Set and Get methods
	age int
}

func NewPerson(name string) *person {     //Factory functions can be used in other packages, which is equivalent to constructors
    return &person{
       Name = name,
    }
}
func (p *person) SetAge(age int){
    if age > 0&&age < 150 {
        p.age = age
    }else{
        fmt.Println("Wrong age range")
    }
}
func(p *person) GetAge() int{
    return p.age
}

main package

package main
import (
	"fmt"
    "go_code/chapter09/model"
)

func main() {
    p := model.person("smith")
    p.SetAge(18)
    fmt.Println(p.Name,"age = " , p.GetAge)
}

2.13.3 succession

1) Basic grammar

type Goods struct {
    Name string
    Price int
}

type Book struct {
    Goods // Here is the nested anonymous structure Goods
    Writer string
}

2) Quick start cases

package main
import(
	"fmt"
)

type Student struct {
    Name string
    Age int
    Score int
}

func(stu *Student) ShowInfo(){
    fmt.Println(stu.Name,stu.Age,stu.Score)
}
func (stu *Student) SetScore(score int) {
    stu.Score = score
}

type Pupil struct{
    Student     //Embedded Student anonymous struct name
}

func (p *Pupil) testing() {
    fmt.Println("Methods of primary school students")
}

type Graduate struct {
    Student     //Embedded Student anonymous struct name
}
func (p *Graduate) testing() {
    fmt.Println("Methods for College Students")
}

func main() {
    pupil := &Pupil{}
    pupil.Student.Age = 8
	pupil.testing()
}

3) Attention

① Structures can use all fields and methods of nested anonymous structures, that is, fields and methods with uppercase and lowercase letters can be used

//b. A.name = "FASD" = = b.name, provided that there is no name variable in B  

③ A structure can be embedded into multiple anonymous structures. If there are the same method name or attribute, you need to specify the anonymous structure to distinguish

④ If a struct is nested with a well-known structure, this pattern is a combination. When accessing the fields or methods of the combined structure, you need to bring the structure name

type D struct{
    Name string
}
type B struct{
    d D
}
func main() {
    var b B
    b.d.Name =" sdf"  //You must bring the anonymous structure name here
}

⑤ After nesting a structure, you can specify the value of each anonymous structure field when creating a structure variable

type D struct{
    Name string
}
type H struct{
    Sex string
}
type B struct{
    D
    H
}
func main() {
    var b B
    b = B{
        D{
            Name : "fads",
        },
        H{
            Sex : "fasd",
        },
    }
}
type D struct{
    Name string
}
type H struct{
    Sex string
}
type B struct{
    *D
    *H
}
func main() {
    var b B
    b = B{
        &D{
            Name : "fads",
        },
        &H{
            Sex : "fasd",
        },
    }
    fmt.Println(*b.D,*b.H)
}

3) Multiple inheritance

type D struct{
    Name string
}
type H struct{
    Sex string
}
type B struct{    //multiple inheritance
    D
    H
}
func main() {
    var b B
    b = B{
        D{
            Name : "fads",
        },
        H{
            Sex : "fasd",
        },
    }
}

✨ In order to ensure the simplicity of the code, it is recommended not to use multiple inheritance

2.13.4 interface

1) Basic grammar

type Usb interface{   //Interface definition
    //Declare two methods
    Start()
    Stop()
}

type Phone struct {
    
}

type Camera struct{
    
}

func (p Phone) Start() {
    fmt.Println("work.....")
}
func (p Phone) Stop() {
    fmt.Println("over.....")
}

func (c Camera) Start() {
    fmt.Println("work.....")
}
func (c Camera) Stop() {
    fmt.Println("over.....")
}


func Computer struct {
    
}
//Receive a variable of Usb interface type
func (c Computer) Working (usb Usb){
    usb.Start()
    usb.Stop()
}

func main() {
    computer := Computer{}
    phone := Phone{}
    camera := Camera{}
    
    computer.Working(phone)
}

2) The interface in Golang does not need to be explicitly implemented. As long as a variable contains all the methods in the interface type, the variable implements the interface. Therefore, there is no keyword such as implementation in Golang

3) Interface considerations and details

package main

import(
	"fmt"
)
type AInterface interface{
    Say()
}

type Stu struct {
    Name string
}
//①
func (stu Stu) Say() {
    fmt.Println("stu Say()")
}


//②
type interger int
func (i integer) Say() {
    fmt.Println("integer Say i =",i)
}


//③
type BInterface interface{
    Hello()
}
type Moster struct{
    
}
func(m Monster) Hello() {
    fmt.Println("hello...")
}
func(m Monster) Say() {
    fmt.Println("say hello...")
}
func main(){
    
    //① The interface itself cannot create an instance, but it can point to a variable of a custom type that implements the interface
    var stu Stu
    //var a AInterface = stu this is an error
    var a AInterface = stu   //√
    a.Say()
    
    //② As long as it is a custom data type, you can implement the interface, not just the structure type
    var i integer = 20
    var b AInterface = i
    b.Say()
    
    //③ A custom type can implement multiple interfaces
    var monster Monster
    var a2 AInterface = monster
    var b2 BInterface = monster
    a2.Say()
    b2.Hello()
}

🤖 You cannot have any variables in a Golang interface

👽 An interface (such as interface A) can inherit multiple individual interfaces (such as interfaces B and C). To implement interface A, you must also implement the methods of interfaces B and C

package main

import(
	"fmt"
)
type AInterface interface{
    Say()
}
type BInterface interface{
    Hello()
}
type CInterface interface{
    AInterface
    BInterface
    test()
}
type Stu struct {
    
}
func (stu Stu)Say(){
    
}
func (stu Stu)Hello(){
    
}
func (stu Stu)test(){
    
}
func main() {
    var stu Stu
    var c CInterface = stu
    a.test()
}

👹 interface is a reference type. If it is not initialized, nil is not

👾 Empty interface interface {}, you can assign any variable to the interface

4) Classic case: sorting slices

package main

import(
	"fmt"
	"math/rand"
	"sort"                       //Call the interface in sort
)
 //Declare Hero structure
type Hero struct{
	Name string
	Age int
}
//Declare a Hero struct slice
type HeroSlice []Hero


//As follows: implement the Inerface interface
func (hs HeroSlice) Len()int{
	return len(hs)
}
//The Less method is to determine what criteria you use to sort
//1. Sort by Hero's age from small to large
func (hs HeroSlice) Less(i, j int) bool {
	return hs[i].Age < hs[j].Age               //In ascending order, if it returns true, Swap will be called to sort
}
func (hs HeroSlice) Swap(i, j int) {
	temp := hs[i]
	hs[i] = hs[j]
	hs[j] = temp
}

func main() {
	var heroes HeroSlice
	for i := 0; i < 10; i++{
		hero := Hero{
			Name : fmt.Sprintf("hero~%d",rand.Intn(100)),
			Age : rand.Intn(100),
		}
		heroes = append(heroes,hero)
	}

	for _,v := range heroes{
		fmt.Println(v)
	}
	//After sorting
	fmt.Println("After sorting..")
	sort.Sort(heroes)
	for _,v := range heroes{
		fmt.Println(v)
	}
}

2.13.5 differences between inheritance and structure

1) Interfaces can be used as a complement to inheritance

2) The value of inheritance lies in the reusability and maintainability of code

3) The value of an interface is to design specifications (Methods) so that other custom types can implement it

2.13.6 polymorphism

1) Polymorphic parameters

As in the example in the interface, usb can receive both phone variables and camera variables

2) Polymorphic array

package main

import(
	"fmt"
)
type Usb interface{   //Interface definition
    //Declare two methods
    Start()
    Stop()
}

type Phone struct {
	Name string
}

type Camera struct{
    Name string
}

func (p Phone) Start() {
    fmt.Println("mobile phone work.....")
}
func (p Phone) Stop() {
    fmt.Println("mobile phone over.....")
}

func (c Camera) Start() {
    fmt.Println("camera work.....")
}
func (c Camera) Stop() {
    fmt.Println("camera over.....")
}


func main() {
    //Define a Usb interface array that can store the structure variables of Phone and camera
	//Here is the polymorphic array
	var usbArr [3]Usb
	usbArr[0] = Phone{"millet"}
	usbArr[1] = Phone{"Huawei"}
	usbArr[2] = Camera{"Sony"}

	for i := 0; i < len(usbArr); i++{
		usbArr[i].Start()
		usbArr[i].Stop()
	}
	fmt.Println(usbArr)
}
//result
/*  
Mobile work
 Phone over
 Mobile work
 Phone over
 Camera work
 Camera over
[{Xiaomi} {Huawei} {Sony}]
*/

② Type assertion

//Example 1
package main

import(
	"fmt"
)

type Point struct{
	x int
	y int
}
func main() {
	var a interface{}
	var point Point = Point{1,2}
	a = point //true

	var b Point
	// b = a is the wrong writing

	b =a.(Point)   //Convert a and judge whether a does not Point to a variable of Point. If yes, it will be converted to Point type. On the contrary, the compiler will report an error
	fmt.Println(b)
    
    //Type assertion 2
    var x interface{}
	var b2 float64 = 1.1
	x = b2
	//Check for errors
	if y, ok := x.(float32); ok{
		fmt.Println("success")
		fmt.Println("y= ", y)
	}else {
		fmt.Println("fail")
	}
	fmt.Println("Continue execution......")
}

Example 2

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-qqjk3thn-1635348855477) (C: \ users \ administrator \ appdata \ roaming \ typora \ user images \ image-20211025222002348. PNG)]

2.14 document operation

2.14.1 basic introduction

1) Stream: the path of data between the data source (file) and the program (memory)

Input stream: the path of data from data source (file) to program (memory)

Output stream: the path of data from program (memory) to data source (file)

2) os.File encapsulates all File related operations. "os" is a package and File is a structure

For example: func Open and func Close use

package main

import (
	"fmt"
	"os"
)

func main(){
	//Open file
	//File is called a file object
	//File is called file pointer
	//File is called file handle
	file, err := os.Open("d:/test.txt")  //If there is no error, you need to have this file in the corresponding location
	if err != nil {
		fmt.Println("open file err=",err)
	}

	fmt.Println("file=",file)

	//Close file
	err = file.Close()
	if err != nil {
		fmt.Println("close file err=",err)

	}
}

2.14.2 reading files

1) Read the file content and display it on the terminal (with buffer)

package main

import (
	"fmt"
	"os"
	"bufio"
	"io"
)
func main(){
	//Open file
	file, err := os.Open("d:/test.txt")  
	if err != nil {
		fmt.Println("open file err=",err)
	}
	defer file.Close()  //Close the file handle in time, otherwise there will be a memory leak

	//Create a * Reader with buffer
	/*
	const {
		defaultBufSize = 4096  //The default buffer is 4096
	}
	*/

	reader := bufio.NewReader(file)
	//Loop to read the contents of the file
	for{
		str, err := reader.ReadString('\n') //It ends when you read a "\ n". str stores the content and err stores the error information
		if err == io.EOF{  //Indicates the end of the file
			break
		}
		fmt.Print(str)
	}
	fmt.Println("End of reading file~~~~")
}

2) One time opening (small file, inefficient if large file)

package main

import (
	"fmt"
	"io/ioutil"
)
func main(){
	file := "d:/test.txt"
	content, err := ioutil.ReadFile(file)    //content is [] byte
	 if err != nil {
		 fmt.Printf("read file err=%v",err)
	 }
	 fmt.Println(string(content))
}

2.14.3 create files and write contents

1) Basic introduction

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

Note: os.OpenFile is a method to open a file at one time. It will open a file with a specified name using the specified options and mode.

Second parameter: file open mode (can be combined)

The third parameter: permission control

2) Case

//Constants package
const (
    O_RDONLY int = syscall.O_RDONLY // Open file in read-only mode
    O_WRONLY int = syscall.O_WRONLY // Open file in write only mode
    O_RDWR   int = syscall.O_RDWR   // Open file in read-write mode
    O_APPEND int = syscall.O_APPEND // Append data to the end of the file when writing
    O_CREATE int = syscall.O_CREAT  // If it does not exist, a new file is created
    O_EXCL   int = syscall.O_EXCL   // For use with O_CREATE, the file must not exist
    O_SYNC   int = syscall.O_SYNC   // Open file for synchronizing I/O
    O_TRUNC  int = syscall.O_TRUNC  // If possible, empty the file when opening
)

① / / create a new file and write 5 sentences of "hello world"

package main

import (
	"fmt"
	"bufio"
	"os"
)

func main() {
    //1. Open the file
    filePath := "d:/abc.txt"
    file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0666)
    if err != nil {
        fmt.Printf("open file err=%v\n",err)
        return
    }
    //Close the file handle in time
    defer file.Close()
    
    //Ready to write
    str := "hello,world\n"
    
    //When writing, use * Writer with cache
    writer := bufio.NewWriter(file)  //Returns a writer
    for i := 0; i < 5; i++{
        writer.WriteString(str)
    }
    
    //Because the writer is cached, when calling the WriterString method, the content is written to the cache first.
    //Therefore, call the Flush method to write the buffered data to the file!!!!
    writer.Flush()
}

② / / open a file and overwrite the original contents of the file with 5 sentences "BLA"

package main

import (
	"fmt"
	"bufio"
	"os"
)

func main() {
    //1. Open the file
    filePath := "d:/abc.txt"
    file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_TRUNC, 0666)  //os.O_TRUNC opens the file and empties the contents
    if err != nil {
        fmt.Printf("open file err=%v\n",err)
        return
    }
    //Close the file handle in time
    defer file.Close()
    
    //Ready to write
    str := "blablablabla\n"
    
    //When writing, use * Writer with cache
    writer := bufio.NewWriter(file)  //Returns a writer
    for i := 0; i < 5; i++{
        writer.WriteString(str)
    }
    
    //Because the writer is cached, when calling the WriterString method, the content is written to the cache first.
    //Therefore, the Flush method is called to actually write the buffered data to the file
    writer.Flush()
}

③ / / add "ABC, hahaha"

package main

import (
	"fmt"
	"bufio"
	"os"
)

func main() {
    //1. Open the file
    filePath := "d:/abc.txt"
    file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_APPEND, 0666)//os.O_APPEND appends data to the end of the file during write operations
    if err != nil {
        fmt.Printf("open file err=%v\n",err)
        return
    }
    //Close the file handle in time
    defer file.Close()
    
    //Ready to write
    str := "ABC,Ha ha ha\n"
    
    //When writing, use * Writer with cache
    writer := bufio.NewWriter(file)  //Returns a writer
    for i := 0; i < 5; i++{
        writer.WriteString(str)
    }
    
    //Because the writer is cached, when calling the WriterString method, the content is written to the cache first.
    //Therefore, the Flush method is called to actually write the buffered data to the file
    writer.Flush()
}

④ / / open an existing file and read out and display the original content on the terminal

package main

import (
	"fmt"
	"bufio"
	"os"
	"io"
)

func main() {
    //1. Open the file
    filePath := "d:/abc.txt"
    file, err := os.OpenFile(filePath, os.O_RDONLY | os.O_APPEND, 0666)// os.O_RDONLY opens the file in read-only mode, and os.O_APPEND appends the data to the end of the file during write operation
    if err != nil {
        fmt.Printf("open file err=%v\n",err)
        return
    }
    //Close the file handle in time
    defer file.Close()

	//First read the contents of the original file and display it on the terminal
	reader := bufio.NewReader(file)
	for {
		str, err := reader.ReadString('\n')
		if  err == io.EOF{
			break
		}
		fmt.Print(str)
	}
    
    //Ready to write
    str := "ABC,wj\n"
    
    //When writing, use * Writer with cache
    writer := bufio.NewWriter(file)  //Returns a writer
    for i := 0; i < 5; i++{
        writer.WriteString(str)
    }
    
    //Because the writer is cached, when calling the WriterString method, the content is written to the cache first.
    //Therefore, the Flush method is called to actually write the buffered data to the file
    writer.Flush()
}

2.14.4 copying documents

package main

import (
	"fmt"
	"io/ioutil"
)
func main() {
//1. Read the contents of abc.txt file
//2. Write the read content to kkk.txt
    
    file1Path := "d:/abc.txt"
    file2Path := "d:/kkk.txt"
    
    data, err := ioutil.ReadFile(file1Path)
    if err != nil {
        //Description there is an error reading the file
        fmt.Println("read file err=%v", err)
        return
    }
    
    err := ioutil.WriteFile(file2Path, data, 0666)
    
    if err != nil{
        fmt.Printf("write file error = ", err)
    }
}

2) Copy files (pictures / movies / mp3)

package main

import (
	"fmt"
    "bufio"
    "os"
    "io"
)

    //Write a function to receive the path of two files
func CopyFile(dstFileName string, srcFileName string)(written int64, err error){  
    srcfile, err := os.Open(srcFileName)
    if err != nil {
        fmt.Printf("open file err = %v\n", err)
    }
    //Get the Reader through srcfile
    reader := bufio.NewReader(srcfile)
    defer srcfile.Close()

    //Open desFileName
    dstFile,  err := os.OpenFile(dstFileName, os.O_WRONLY | os.O_CREATE, 0666)
    if err != nil {
        fmt.Printf("open file err=%v\n", err)
        return
    }

    //Get the Writer through dstFile
    writer := bufio.NewWriter(dstFile)
    defer dstFile.Close()

    return io.Copy(writer, reader)//Copy function in io package
}
func main() {
    srcFile := "d:/test/picture.png"
    dstFile := "d:/abc.png"
    CopyFile(dstFile, srcFile)
}

2.14.5 statistics of different types of characters

package main

import (
	"fmt"
    "bufio"
    "os"
    "io"
)
type CharCount struct {
    ChCount int  //Record English letters
    NumCount int //Number of recorded numbers
    SpaceCount int //Record the number of spaces
    OtherCount int //Record the number of other characters
}

func main() {
    //Open a file and create a Reader
    //Without reading a line, count how many English, numbers, spaces and other characters there are in the changed line
    //Then save the results to a structure
    fileName := "d:/abc.txt"
    file, err := os.Open(fileName)
    if err != nil {
        fmt.Printf("err = %v\n", err)
    	return
    }
    defer file.Close()
    //Define a CharCount instance
    var count CharCount
    //Create a Reader
    reader := bufio.NewReader(file)
    
    //Start looping reading the contents of fileName
    for {
        str, err := reader.ReadString('\n')
        if err == io.EOF{
            break
        }
    }
    //Traverse str for statistics
    for _, v = range str {
        fmt.Println(str)
    }
}

2.14.5 how many English, numbers, spaces and other characters are there in the statistical document

package main

import (
	"fmt"
    "bufio"
    "os"
    "io"
)
type CharCount struct {
    ChCount int  //Record English letters
    NumCount int //Number of recorded numbers
    SpaceCount int //Record the number of spaces
    OtherCount int //Record the number of other characters
}

func main() {
    //Open a file and create a Reader
    //Without reading a line, count how many English, numbers, spaces and other characters there are in the changed line
    //Then save the results to a structure
    fileName := "d:/abc.txt"
    file, err := os.Open(fileName)
    if err != nil {
        fmt.Printf("err = %v\n", err)
    	return
    }
    defer file.Close()
    //Define a CharCount instance
    var count CharCount
    //Create a Reader
    reader := bufio.NewReader(file)
    
    //Start looping reading the contents of fileName
    for {
        str, err := reader.ReadString('\n')
        if err == io.EOF{     //Exit at the end of the file
            break
        }
        //Traverse str for statistics
        for _, v := range str {
        
            switch  {        //Instead of v to match, it is treated as an if branch structure statement
            case v >= 'a' && v <= 'z':
                fallthrough //Penetration, which forces the execution of the next line of statements
            case v >= 'A' && v <= 'Z':
                    count.ChCount++
            case v == ' ' || v == '\t':
                    count.SpaceCount++  
            case v >= '0' && v <= '9':
                    count.NumCount++
            default :
                    count.OtherCount++       
            }
        }
    }

    //Number of output statistics
    fmt.Printf("The number of characters is=%v The number of numbers is=%v The number of spaces is=%v The number of other characters is=%v",
    count.ChCount, count.NumCount,  count.SpaceCount, count.OtherCount)
}

2.14.6 flag package to parse command line parameters

package main

import (
	"fmt"
    "flag"
)

func main ()  {
    var user string
    var pwd string
    var host string
    var port int

    //User is the parameter value after - u entered in the user command line
    flag.StringVar(&user,"u","","The user name is empty by default")
    flag.StringVar(&pwd,"pwd","","Password, blank by default")
    flag.StringVar(&host,"host","localhost","Host name, empty by default")
    flag.IntVar(&port,"port",3306,"Port number, 3306 by default")

    //transformation
    flag.Parse()

    //Output results
    fmt.Printf("user=%v pwd=%v host=%v port=%v",user,pwd,host,port)
}

Terminal: D:\Go code \ SRC \ go_ code\chapter12> go build -o test.exe test.go

D:\Go code \ SRC \ go_ code\chapter12> test.exe -u root -pwd 132465 -host
127.0.0.5 -port 8080

2.15 test whether the function is executed correctly

//cal_test file
package main
import(
	_"fmt"
	"testing" //Introducing the testing framework in go
)

//Write a test case to test whether addUpper is correct
func TestAddUpper(t *testing.T)  {
	
	//call
	res := addUpper(10)
	if res != 55 {
		t.Fatalf("AddUpper(10) Execution error, expected value=%v actual value=%v\n", 55, res)
	}

	//If correct, output the log
	t.Logf("AddUpper(10) Correct execution....")
}
//Tested file
package main

//A function under test
func addUpper(n int) int{
	res := 0
	for i := 1; i <= n - 1; i++ {
		res += i
	}
	return res
}

result:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ykka4x5d-1635348855479) (C: \ users \ administrator \ appdata \ roaming \ typora \ user images \ image-20211027233258247. PNG)]

Schematic diagram of function execution:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-0av1jaxl-1635348855481) (C: \ users \ administrator \ appdata \ roaming \ typora \ typora user images \ image-20211027232937740. PNG)]

matters needing attention:

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-8ovme5ya-1635348855483) (C: \ users \ administrator \ appdata \ roaming \ typora \ user images \ image-20211027233031706. PNG)]

Count int / / record the number of spaces
OtherCount int / / record the number of other characters
}

func main() {
//Open a file and create a Reader
//Without reading a line, count how many English, numbers, spaces and other characters there are in the changed line
//Then save the results to a structure
fileName := "d:/abc.txt"
file, err := os.Open(fileName)
if err != nil {
fmt.Printf("err = %v\n", err)
return
}
defer file.Close()
//Define a CharCount instance
var count CharCount
//Create a Reader
reader := bufio.NewReader(file)

//Start looping reading the contents of fileName
for {
    str, err := reader.ReadString('\n')
    if err == io.EOF{     //Exit at the end of the file
        break
    }
    //Traverse str for statistics
    for _, v := range str {
    
        switch  {        //Instead of v to match, it is treated as an if branch structure statement
        case v >= 'a' && v <= 'z':
            fallthrough //Penetration, which forces the execution of the next line of statements
        case v >= 'A' && v <= 'Z':
                count.ChCount++
        case v == ' ' || v == '\t':
                count.SpaceCount++  
        case v >= '0' && v <= '9':
                count.NumCount++
        default :
                count.OtherCount++       
        }
    }
}

//Number of output statistics
fmt.Printf("The number of characters is=%v The number of numbers is=%v The number of spaces is=%v The number of other characters is=%v",
count.ChCount, count.NumCount,  count.SpaceCount, count.OtherCount)

}

### 2.14.6 flag package to parse command line parameters

```go
package main

import (
	"fmt"
    "flag"
)

func main ()  {
    var user string
    var pwd string
    var host string
    var port int

    //User is the parameter value after - u entered in the user command line
    flag.StringVar(&user,"u","","The user name is empty by default")
    flag.StringVar(&pwd,"pwd","","Password, blank by default")
    flag.StringVar(&host,"host","localhost","Host name, empty by default")
    flag.IntVar(&port,"port",3306,"Port number, 3306 by default")

    //transformation
    flag.Parse()

    //Output results
    fmt.Printf("user=%v pwd=%v host=%v port=%v",user,pwd,host,port)
}

Terminal: D:\Go code \ SRC \ go_ code\chapter12> go build -o test.exe test.go

D:\Go code \ SRC \ go_ code\chapter12> test.exe -u root -pwd 132465 -host
127.0.0.5 -port 8080

2.15 test whether the function is executed correctly

//cal_test file
package main
import(
	_"fmt"
	"testing" //Introducing the testing framework in go
)

//Write a test case to test whether addUpper is correct
func TestAddUpper(t *testing.T)  {
	
	//call
	res := addUpper(10)
	if res != 55 {
		t.Fatalf("AddUpper(10) Execution error, expected value=%v actual value=%v\n", 55, res)
	}

	//If correct, output the log
	t.Logf("AddUpper(10) Correct execution....")
}
//Tested file
package main

//A function under test
func addUpper(n int) int{
	res := 0
	for i := 1; i <= n - 1; i++ {
		res += i
	}
	return res
}

result:

Schematic diagram of function execution:

matters needing attention:

Tags: Go Back-end

Posted on Wed, 27 Oct 2021 10:51:23 -0400 by louie