language features

  1. Deployment is simple:

    1. Can be directly compiled into machine code for execution
    2. Does not depend on other libraries
    3. Deploy directly by running
  2. Statically typed languages: hidden problems can be detected at compile time
  3. Concurrency at the language level: Innate support for concurrency, making full use of multi-core
  4. Powerful standard library:

    1. runtime system scheduling mechanism
    2. Efficient GC garbage collection
    3. Rich standard library
  5. Easy to learn: 25 keywords, support inline C syntax, object-oriented, cross-platform

Configure installation

Mac download address: https://dl.google.com/go/go1.17.3.darwin-amd64.pkg

Installation path: /usr/local/go

Configure environment variables:

vi ~/.bash_profile
 export GOPATH=$HOME/go
source ~/.bash_profile

common problem

1. go.mod file not found in current directory or any parent directory

Solved: go env -w GO111MODULE=auto

Syntax Note

  1. It is not recommended to add a semicolon at the end of the expression
  2. Import multiple packages

     import (
        "fmt"
        "time"
    )
  3. Function curly braces must go with the function name
vim hello.go
 package main

import "fmt"
func main() {
    fmt.Println("Hello Go!")
}

compile and execute

 go run hello.go

compile

 go build hello.go

implement

 ./hello

variable var

  1. declare a variable (default value is 0)

     var a int
  2. declare a variable and initialize a value

     var b int = 100
  3. Omit the type during initialization, and automatically match the data type by value (not recommended)

     var c = 100
    var cc = "abcd"
    
    fmt.Printf("cc=%s,cc=%T",cc,cc)//cc=abcd,cc=string
  4. Omit the var keyword and automatically match (commonly used)

     e := 100
    f := "abcd"

Remarks: Method 1.2.3 can declare global variables outside the function body; 4 can only declare local variables inside the function body

  1. Declare a multiline variable

     var xx, yy int = 100, 200
    var mm, nn = 100, "abc"
    
    var (
        cc int = 100
        dd bool = true
    )
    fmt.Println("cc=",cc,"dd=",dd)

constant const

Constants are not allowed to be modified
 const a int = 100
const (
    BEIJING = 1
    SHANGHAI = 2
)
iota: used with const, each line is accumulated, the first line defaults to 0
 const (
    BEIJING = 10 * iota //0
    SHANGHAI                         //10
    SHENZHEN                         //20
)
const (
        a, b = iota+1,iota+2//iota=0, a=1, b=2
    c, d                                //iota=1, c=1, d=3
    g, h = iota*2,iota*3//iota=3, g=6, h=9
)

function

basic functional form

 func test(a string, b int) int {
        return 100
}

Multiple return values

 //匿名
func test(a string, b int) (int, int) {
        return 666, 777
}
//有形参名(初始化默认为0)
func test(a string, b int) (r1 int, r2 int) {
        r1 = 1000
        r2 = 2000
        return
}

method as parameter

 func ShowBookInfoAndPrice(bookName, author string, price float64) (string, float64) {
    return bookName + author, price
}

//函数式编程
func PrintBookInfo(do func(string, string, float64) (bookInfo string, finalPrice float64),
    bookName, author string, price float64) {
    bookInfo, finalPrice := do(bookName, author, price)
    fmt.Println("bookInfo:", bookInfo)
    fmt.Println("finalPrice:", finalPrice)
}

func main() {
    PrintBookInfo(ShowBookInfoAndPrice, "AAA", "BBB", 99.99)
}

anonymous function

 //匿名函数
func PrintBookInfo2(bookName, author string, price float64) {
    do := func(string, string, float64) (bookInfo string, finalPrice float64) {
        return bookName + author, price
    }
    fmt.Println(do(bookName, author, price))
}

func main() {
    PrintBookInfo2("AAA", "BBB", 99.99)
}

variable parameter

 //可变参数
func PrintBookNames(bookList ...string) {
    r := ""
    for _, item := range bookList {
        r += item
    }
    fmt.Println(r)
}
func main() {
    PrintBookNames("AAA", "BBB", "CCC")
}

Conditional judgment

 package main

import (
    "fmt"
    "net/http"
)

func VisitUrl(url string) (int, error) {
    res, err := http.Get(url)
    defer res.Body.Close()
    if err != nil {
        fmt.Println("ERROR:", err)
        return res.StatusCode, err
    } else {
        fmt.Println("OK:", res.StatusCode)
        return res.StatusCode, err
    }

}

func SwitchShow(url string) {
    if code, err := VisitUrl(url); err != nil {
        fmt.Println("Switch Error:", err)
    } else {
        switch code {
        case 200:
            fmt.Println("请求成功")
        case 404:
            fmt.Println("网址不存在")
        default:
            panic("未知错误")
        }
    }
}

func main() {
    SwitchShow("http://www.baidu.com")
}

import and init

hello.go

 package main
import (
    "GoStudy/lib1"
    "GoStudy/lib2"
)
func main() {
    lib1.Lib1Test();  //在外部调用的函数名首字母必须大写
    lib2.Lib2Test();    
}
//输出结果
//lib1.init()...
//lib2.init()...
//Lib1Test()...
//Lib2Test()...

lib1/lib1.go

 package lib1
import "fmt"
func Lib1Test()  {
    fmt.Println("Lib1Test()...")
}
func init()  {
    fmt.Println("lib1.init()...")
}

lib2/lib2.go

 package lib2
import "fmt"
func Lib2Test()  {
    fmt.Println("Lib2Test()...")
}
func init()  {
    fmt.Println("lib2.init()...")
}

Notice:

  1. Import an anonymous package (do not execute the functions inside the package, but execute the init method)

     import _ "GoStudy/lib2"
  2. import package alias

     import l2 "GoStudy/lib2"
    func main() {
        l2.Lib2Test();    
    }
  3. Import into the current package (functions can be called directly)

     import . "GoStudy/lib2"
    func main() { 
        Lib2Test();    
    }

pointer*

Note: Pointers in the GO language do not allow operations.

 package main
import "fmt"
func changeValue(p *int)  {
   *p = 10;
}
func main() { 
    var a = 1
    changeValue(&a)
    //p = &a
    //*p = 10
    fmt.Println("a =",a) //a = 10
}

defer

The mechanism for executing before the end of the function (first in, last out, executed after the return method)
 package main
import "fmt"
func func1()  {
    fmt.Println("func1()...")
}
func func2()  {
    fmt.Println("func2()...")
}
func func3()  {
    fmt.Println("func3()...")
}
func returnAndDefer() int {
    defer func1()
    defer func2()
    defer func3()
    return returnFunc()
}
func returnFunc() int {
    fmt.Println("returnFunc()...")
    return 0
}
func main() { 
    returnAndDefer()
}
//执行顺序:
returnFunc()...
func3()...
func2()...
func1()...

Arrays and Dynamic Arrays

fixed length array
 package main
import "fmt"
func test(arr []int)  {
    arr[0] = 111
}
func main() { 
    //固定长度的数组
    var myArr []int
    //数组遍历
    test(myArr)//myArr[0]不变
    for k, v := range myArr2 {
        fmt.Println("index=",k,"value=",v)
    }
}
Dynamic arrays (slices)

Dynamic arrays are passed by reference, actually passing a pointer to the array, pointing to the same piece of memory

Dynamic array parameters of different lengths are the same

 package main
import "fmt"
func test(arr []int)  {
    arr[0] = 111
}
func main() { 
    //固定长度的数组
    myArr := []int{1,2,3,4}
    //数组遍历
    test(myArr)//myArr[0]不变
    for k, v := range myArr {
        fmt.Println("index=",k,"value=",v)
    }
}
//输出结果
index= 0 value= 111
index= 1 value= 2
index= 2 value= 3
index= 3 value= 4

Note: _ means anonymous variable

How slices are declared
  1. Declare slice1 as a slice, and initialize it, the default value is 1, 2, 3, and the length len is 3

     slice1 := []int{1, 2, 3}
  2. Declare slice2 to be a slice, but does not allocate space, need to allocate space (initialization value is 0)

     var slice2 = []int
    slice2 = make([]int, 3)
  3. Declare slice3 as a slice and allocate space via make (initialization value is 0)

     var slice3 []int = make([]int, 3)
  4. Declare slice4 as a slice and allocate space through make (initialization value is 0), deduce slice4 as a slice through := (commonly used)

     slice4 := make([]int, 3)
appending of slices

len: length, indicating the distance between the left pointer and the right pointer

cap: capacity, indicating the distance from the left pointer to the end of the underlying array

Slice expansion mechanism: When appending, if the length exceeds the capacity, the capacity will be doubled (5 -> 10 -> 20)
 var numbers = make([]int, 3, 5)//长度3, 容量5
fmt.Printf("len=%d,cap=%d,slice=%v",len(numbers),cap(numbers),numbers)
//len=3,cap=5,slice=[0 0 0]

Append an element 1 to numbers

 numbers = append(numbers, 1)
fmt.Printf("len=%d,cap=%d,slice=%v",len(numbers),cap(numbers),numbers)
//len=4,cap=5,slice=[0 0 0 1]

Append an element 2 to numbers

 numbers = append(numbers, 2)
fmt.Printf("len=%d,cap=%d,slice=%v",len(numbers),cap(numbers),numbers)
//len=5,cap=5,slice=[0 0 0 1 2]

Append elements to a full slice

 numbers = append(numbers, 3)
fmt.Printf("len=%d,cap=%d,slice=%v",len(numbers),cap(numbers),numbers)
//len=6,cap=10,slice=[0 0 0 1 2 3]
cutting of slices
 s := []int{1,2,3}
s1 := s[0:2]
s2 := make([]int, 3)
copy(s2, s)//将s中的值,依次copy到s2
s1[0] = 100
fmt.Println(s)//[100 2 3]
fmt.Println(s1)//[100 2]
fmt.Println(s2)//[1 2 3]

map

Declaration method
  1. method one:

    1. Declare that myMap1 is a map type, the key is a string, and the value is a string
    2. Before using map, you need to use make to allocate data space to map
     var myMap1 map[string]string
    myMap1 = make(map[string]string, 10)
    myMap1["a"] = "aaa"
    myMap1["b"] = "bbb"
  2. Method two:

     myMap2 := make(map[int]string)
    myMap2[0] = "a"
    myMap2[1] = "b"
    fmt.Println(myMap2) //map[0:a 1:b]
  3. way three

     myMap3 := map[int]string {
        0 : "a",
        1 : "b",
    }
    fmt.Println(myMap3) //map[0:a 1:b]
How to use
Map is also passed by reference, and the pointer address is passed when it is used as a parameter.
  1. Add to

     myMap2 := make(map[int]string)
    myMap2[0] = "a"
    myMap2[1] = "b"
  2. traverse

     for k, v := range myMap2 {
        fmt.Printf("k=%d,v=%s\n",k,v)
    }
  3. delete

     delete(myMap2, 0)
  4. Revise

     myMap2[0] = "c"

object oriented

structure

  1. definition

     type Book struct {
        title string //类的属性首字母大写表示公有,否则为私有
        auth string
    }
  2. use

     var book1 Book
    book1.title = "Golang"
    book1.auth = "Tom"
    fmt.Println(book1)//{Golang Tom}
    
    book2 := Book{title:"aaa",auth:"bbb"}
    fmt.Println(book2)//{aaa bbb}
    
    book3 := Book{"aaa","bbb"}
    fmt.Println(book3)//{aaa bbb}
  3. Pass (pass is a copy)

     func changeBook(book Book)  {
        book.title="XXX"
    }
    func main() { 
        var book1 Book
        book1.title = "Golang"
        book1.auth = "Tom"
        changeBook(book1)
        fmt.Println(book1)//{Golang Tom}
    }

kind

Encapsulation: class name, attribute name, method name with the first letter capitalized to indicate that it can be accessed externally
this is a copy (copy) of the object on which the method was called
 func (this *Book) setName(title string)  {
    this.title=title
}
func (this Book) setAuth(auth string)  {
    this.auth=auth
}
func main() { 
    book := Book{title:"aaa",auth:"bbb"}
    book.setName("ccc")
    book.setAuth("ddd")
    fmt.Println(book)//{ccc bbb} 
}
inherit
 package main
import "fmt"
type Human struct {
    name string
    sex string
}
type SuperMan struct {
    Human
    level int
}
func (this *Human) Eat()  {
    fmt.Println("Human Eat...")
}
func (this *Human) Walk()  {
    fmt.Println("Human Walk...")
}
func (this *SuperMan) Walk()  {
    fmt.Println("SuperMan Walk...")
}
func (this *SuperMan) Fly()  {
    fmt.Println("SuperMan Fly...")
}
func main() { 
    tom := Human{"aaa","bbb"}
    tom.Eat() //Human Eat...
    tom.Walk()//Human Walk...
    //s :=SuperMan{Human{"ccc","ddd"},100}
    var s SuperMan
    s.name = "Sss"
    s.sex = "man"
    s.level= 88
    s.Walk()//SuperMan Walk...
    s.Fly()//SuperMan Fly...
}
polymorphism
The interface is essentially a pointer to the parent class

Basic elements:

  1. has a parent class (interface)
  2. There are subclasses that implement all the interface methods of the parent class
  3. A variable (pointer) of the superclass type points (references) to a specific data variable of the subclass
 package main
import "fmt"
type AnimalIF interface {
    Sleep()
    GetColor() string
}
type Cat struct {
    color string
}
func (this *Cat) Sleep()  {
    fmt.Println("Cat Sleep...")
}
func (this *Cat) GetColor() string {
    return this.color
}
type Dog struct {
    color string
}
func (this *Dog) Sleep()  {
    fmt.Println("Dog Sleep...")
}
func (this *Dog) GetColor() string {
    return this.color
}
func showAnimal(animal AnimalIF)  {
    animal.Sleep()
    fmt.Println("color=",animal.GetColor())
}
func main() { 
    var animal AnimalIF//接口的数据类型:父类指针
    animal = &Cat{"White"}
    animal.Sleep()//Cat Sleep...
    fmt.Println("color=",animal.GetColor())//color= White

    dog := Dog{"Yellow"}
    showAnimal(&dog)
    //Dog Sleep...
    //color= Yellow
}
Universal data type interface{} (empty interface)
interface{} type assertion mechanism: arg.(string)
 package main
import "fmt"

type Book struct {
    tile string
}
func test(arg interface{}){
    fmt.Println(arg)
    //断言
    _, ok := arg.(string)
    if !ok {
        fmt.Println("arg is not string")
    }else{
        fmt.Println("arg is string")
    }
}
func main() { 
    book := Book{"Golang"}
    test(book)//{Golang}
    test(123)//123
    test("hello")//hello
}
variable type
  1. variable pair

    1. type

      1. static type: int/string
      2. Concrete type: The specific data type that the interface refers to (the type visible to the system runtime)
    2. value
 package main
import "fmt"
type Reader interface {
    ReadBook()
}
type Writer interface {
    WriteBook()
}
type Book struct {

}
func (this *Book) ReadBook() {
    fmt.Println("Read a book.")
}
func (this *Book) WriteBook() {
    fmt.Println("Write a book.")
}
func main() { 
    b := &Book{}//b: pair<type:Book, value:Book{}地址>
    var r Reader//r: pair<type: 空, value: 空>
    r = b       //r: pair<type:Book, value:Book{}地址>
    r.ReadBook()
    var w Writer  
    w = r.(Writer)//w: pair<type:Book, value:Book{}地址>
    //断言有两步:得到动态类型 type,判断 type 是否实现了目标接口。
    //这里断言成功是因为 type 是 Book,而 Book 实现了 Writer 接口
    w.WriteBook()
}

reflection

example 1:

 package main
import (
    "fmt"
    "reflect"
)
func reflectNum(arg interface{}){
    fmt.Println("type:", reflect.TypeOf(arg))
    fmt.Println("value:", reflect.ValueOf(arg))
}
func main() { 
    var num float64 = 1.34556
    reflectNum(num)
    //type: float64
    //value: 1.34556
}

Example 2:

 package main
import (
    "fmt"
    "reflect"
)
type User struct {
    Id int
    Name string
    Age int
}
func (this User) Call(){
    fmt.Printf("User: %v", this)
}
func DoFieldAndMethod(input interface{}){
    inputType := reflect.TypeOf(input)
    inputValue := reflect.ValueOf(input)
    //遍历属性
    for i := 0; i < inputType.NumField(); i++ {
        field := inputType.Field(i)
        value := inputValue.Field(i).Interface()
        fmt.Printf("%s:%v = %v\n",field.Name, field.Type, value)
    }
    //Id:int
    //Name:string = Lilei
    //Age:int = 18
    //遍历方法(注意指针类型的结构体方法无法打印)
    for i := 0; i < inputType.NumMethod(); i++ {
        inputMethod := inputType.Method(i)
        fmt.Printf("%s:%v\n",inputMethod.Name, inputMethod.Type)
    }
    //Call:func(main.User)
}
func main() { 
    user := User{1, "Lilei", 18}
    DoFieldAndMethod(user)
}

Structure Tag Tag

 package main
import (
    "fmt"
    "reflect"
)
type User struct {
    Name string `info:"name" doc:"姓名"`
    Age int `info:"age" doc:"年龄"`
}
func findTag(input interface{}){
    inputType := reflect.TypeOf(input).Elem()
    //遍历属性
    for i := 0; i < inputType.NumField(); i++ {
        taginfo := inputType.Field(i).Tag.Get("info")
        tagdoc := inputType.Field(i).Tag.Get("doc")
        fmt.Printf("info:%s doc:%s\n",taginfo, tagdoc)
    }
}
func main() { 
    var u User
    findTag(&u)
    //info:name doc:姓名
    //info:age doc:年龄
}

Application of structure tags in json

 package main
import (
    "fmt"
    "encoding/json"
)
type User struct {
    Name string `json:"name"`
    Age int `json:"age"`
    Hobby []string `json:"hobby"`
}
func main() { 
    user := User{"lilei", 18, []string{"dance","football"}}
    //json编码
    jsonStr, err := json.Marshal(user)
    if err != nil {
        fmt.Println("Json marshal error.")
        return
    }
    fmt.Printf("json = %s",jsonStr)//json = {"name":"lilei","age":18,"hobby":["dance","football"]}
    //json解码
    user1 := User{}
    err = json.Unmarshal(jsonStr, &user1)
    if err != nil {
        fmt.Println("Json unmarshal error.")
        return
    }
    fmt.Println(user1)//{lilei 18 [dance football]}
}

IT小马
1.2k 声望166 粉丝

Php - Go - Vue - 云原生