GO language fast learning | PHP to GO notes

Posted by bigc79 on Tue, 08 Feb 2022 14:29:26 +0100

web Framework

Popularity ranking

https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#popularity

beego

https://beego.me/products

echo

https://echo.labstack.com/

gin go community document

https://learnku.com/docs/gin-gonic/2019

See cloud gin document

https://www.kancloud.cn/shuangdeyu/gin_book/949418

Quick use of gin

https://www.jianshu.com/p/98965b3ff638

gin-admin-vue

https://www.gin-vue-admin.com/docs/gorm

Official website

https://golang.org/dl/

Chinese official website

https://go-zh.org/pkg/

go common library

https://github.com/jobbole/awesome-go-cn

View version number

go version

View env

go env

==Can't pull down the bag==

export GOPATH=/usr/local/go/bin
export GOPROXY=https://goproxy.io
export PATH=$PATH:$GOPATH
export GO111MODULE=on

Open module

go env -w GO111MODULE=on

Set agent

go env -w GOPROXY=https://goproxy.io,direct

Microservice framework

go-kit

go micro

go-zero

Common web address

go Basics

go basics v1

go basics v2---micro

Rookie GO

Documentation and Technology Forum

gomod detailed use

go official website Library

==go official pkg Chinese==

Example of pgk used by github

go mod usage

Basic data type

String operation

Local gorm struct generation

https://github.com/xxjwxc/gormt.git

Local struct generation

https://github.com/hantmac/fuckdb.git

1 use docker-composer Mode start
2 encounter docker Containers cannot be linked locally mysql When 
Locally mysql
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES

struct generation

go get -u github.com/gohouse/converter

err := converter.NewTable2Struct().
    SavePath("./model.go").
    Dsn("root:root@tcp(127.0.0.1:3306)/foroo_beta_shopify?charset=utf8").
    TagKey("db").
    EnableJsonTag(true).
    Table("fr_store").
    Run()
fmt.Println(err)
return

Basics

Variables or methods use lowercase, which is equivalent to the initial letter of protect, and uppercase is equivalent to public

Use + to splice strings

Variable declaration var age int;

The data types in constants can only be Boolean, numeric (integer, floating point and complex) and string.

var f string = "Runoob" can be abbreviated as F: = "runoob":

Every statement outside a function must start with a keyword (var, const, func, etc.)

: = cannot be used outside a function.

_ It is mostly used for occupation, indicating that the value is ignored. import _ "./hello"_ The placeholder will only execute init in the import package, and other methods cannot be called

iota is a constant counter of go language, which can only be used in constant expressions

strconv.Itoa(97) converts a number into a string type. string(97)go's own will convert the number into the corresponding ascii code

  const (
            n1 = iota //0
            n2        //1
            n3        //2
            n4        //3
        )

map, slice, chan, pointer and interface are passed by reference by default.

Mutex var lock sync Mutex

var x int64
var wg sync.WaitGroup
var lock sync.Mutex

func add() {
    for i := 0; i < 5000; i++ {
        lock.Lock() // Lock
        x = x + 1
        lock.Unlock() // Unlock
    }
    wg.Done()
}
func main() {
    wg.Add(2)
    go add()
    go add()
    wg.Wait()
    fmt.Println(x)
}

It should be noted that the read-write mutex lock is very suitable for the scenario of more reading and less writing. If there is little difference between reading and writing operations, the advantages of the read-write lock will not be brought into play.

var (
    x      int64
    wg     sync.WaitGroup
    lock   sync.Mutex
    rwlock sync.RWMutex
)

func write() {
    // lock.Lock() / / add mutex lock
    rwlock.Lock() // Write lock
    x = x + 1
    time.Sleep(10 * time.Millisecond) // Assume that the read operation takes 10 milliseconds
    rwlock.Unlock()                   // Write unlock
    // lock.Unlock() / / unlock the mutex
    wg.Done()
}

func read() {
    // lock.Lock() / / add mutex lock
    rwlock.RLock()               // Read lock
    time.Sleep(time.Millisecond) // Suppose the read operation takes 1 millisecond
    rwlock.RUnlock()             // Interpretation lock
    // lock.Unlock() / / unlock the mutex
    wg.Done()
}

func main() {
    start := time.Now()
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go write()
    }

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go read()
    }

    wg.Wait()
    end := time.Now()
    fmt.Println(end.Sub(start))
}

sync.Once actually contains a mutex and a Boolean value. The mutex ensures the security of Boolean value and data, and the Boolean value is used to record whether the initialization is completed. This design can ensure that the initialization operation is concurrent and safe, and the initialization operation will not be executed many times.

var icons map[string]image.Image

var loadIconsOnce sync.Once

func loadIcons() {
    icons = map[string]image.Image{
        "left":  loadIcon("left.png"),
        "up":    loadIcon("up.png"),
        "right": loadIcon("right.png"),
        "down":  loadIcon("down.png"),
    }
}

// Icon is concurrency safe
func Icon(name string) image.Image {
    loadIconsOnce.Do(loadIcons)
    return icons[name]
}

==goroutine high and send operation map using sync Map to operate==

//sync.Map has built-in operation methods such as Store, Load, LoadOrStore, Delete and Range
var m = sync.Map{}

func main() {
    wg := sync.WaitGroup{}
    for i := 0; i < 20; i++ {
        wg.Add(1)
        go func(n int) {
            key := strconv.Itoa(n)
            m.Store(key, n)
            value, _ := m.Load(key)
            fmt.Printf("k=:%v,v:=%v\n", key, value)
            wg.Done()
        }(i)
    }
    wg.Wait()
}

==The lock operation in the code will be time-consuming and expensive because it involves the context switching in kernel state. For basic data types, we can also use atomic operation to ensure concurrency security, because atomic operation is a method provided by Go language, which can be completed in user state, so its performance is better than locking operation. Atomic operations in Go language are provided by the built-in standard library sync/atomic==

// Atomic operation version addition function
func atomicAdd() {
    atomic.AddInt64(&x, 1)
    wg.Done()
}

make is only used for the initialization of slice, map and channel, and returns the three reference types themselves

The reference address between variables can be changed directly

package main
func swap(a, b *int) {
    var temp int
    temp = *a
    *a = *b
    *b = temp
}

func main() {
    var a, b = 1, 2
    swap(&a, &b)

    fmt.Println(a)
    fmt.Println(b)
}
//Pointer small case
var a int
fmt.Println(&a)
var p *int
p = &a
*p = 20
fmt.Println(a)

When assigning parameters, you can directly pass an array or slice without assigning them one by one. Pay special attention to adding "..." after the parameters

package main

import (
    "fmt"
)

func test(s string, n ...int) string {
    var x int
    for _, i := range n {
        x += i
    }

    return fmt.Sprintf(s, x)
}

func main() {
    s := []int{1, 2, 3}
    res := test("sum: %d", s...)    // slice...  Expand slice
    println(res)
}

"_" Identifier used to ignore a return value of a function

The return statement without parameters returns the current value of each return variable. This usage is called "bare" return.

func add(a, b int) (c int) {
    c = a + b
    return
}

func calc(a, b int) (sum int, avg int) {
    sum = a + b
    avg = (a + b) / 2

    return
}

func main() {
    var a, b int = 1, 2
    c := add(a, b)
    sum, avg := calc(a, b)
    fmt.Println(a, b, c, sum, avg)
}

Named return parameters allow defer deferred calls to be read and modified through closures.

defer is first in and last out

package main

func add(x, y int) (z int) {
    defer func() {
        z += 100
    }()

    z = x + y
    return
}

func main() {
    println(add(1, 2)) 
}

Define a one-dimensional array

var a [5]int = [5]int{1,2,5,6,7}
var a = [...]int{1,2,3,5,6}
 d := [...]struct {
        name string
        age  uint8
    }{
        {"user1", 10}, // Element types can be omitted.
        {"user2", 20}, // Don't forget the comma on the last line.
    }

"..." cannot be used to define the second dimension of a two-dimensional array

var b [3][2]int = [3][2]int{{1,2},{3,4},{5,6}}
var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}

Define slice

overall situation:
var arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
var slice0 []int = arr[start:end] 
var slice1 []int = arr[:end]        
var slice2 []int = arr[start:]        
var slice3 []int = arr[:] 
var slice4 = arr[:len(arr)-1]      //Remove the last element of the slice
 Local:
arr2 := [...]int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
slice5 := arr[start:end]
slice6 := arr[:end]        
slice7 := arr[start:]     
slice8 := arr[:]  
slice9 := arr[:len(arr)-1] //Remove the last element of the slice
//Create slices with make
var slice []type = make([]type, len)
slice  := make([]type, len)
slice  := make([]type, len, cap)

Define map

    scoreMap := make(map[string]int)
    scoreMap["Zhang San"] = 90
    scoreMap["Xiao Ming"] = 100
    // If the key exists, ok is true and V is the corresponding value; There is no zero value with ok as false and V as value type
    v, ok := scoreMap["Zhang San"]
    if ok {
        fmt.Println(v)
    } else {
        fmt.Println("No one was found")
    }
    //Use the delete() function to delete key value pairs
      delete(scoreMap, "Xiao Ming")//Delete Xiao Ming: 100 from the map

Array output sorted by subscript

    tetcc := make(map[int]string,5)
    tetcc[1] = "smallsha"
    tetcc[5] = "smallsha1"
    tetcc[3] = "smallsha2"
    sli := []int{}
    for i := range tetcc {
        sli = append(sli,i)
    }
    sort.Ints(sli)
    for i := 0; i < len(tetcc); i++ {
        fmt.Println("content",tetcc[sli[i]])
    }

    fmt.Printf("%#v\n", sli)
    return

if judgment

    if test2 :=19; test2> 20 {
        fmt.Println("test11212121212")
    }else if test2 < 20 {
        fmt.Println("test1111")
    }

switch usage

    test3 := 80
    switch test3 {
    case 80:
        fmt.Println("1")
        fallthrough  //You can use fallthrough to enforce the following case code.
    case 90:
        fmt.Println("2")
    case 100:
        fmt.Println("3")
    default:
        fmt.Println("default")

    }

Multiple parameter calls

   func test(s string, n ...int) string {
    var x int
    for _, i := range n {
        x += i
    }

    return fmt.Sprintf(s, x)
}
     s := []int{1, 2, 3}
    res := test("sum: %d", s...)    // slice...  Expand slice
    println(res)

Closure usage

func a() func() int  {
    i := 0
    b := func() int{
        i++
        fmt.Println(i)
        return i
    }
    return b
}

    ccccc := a()
    ccccc()
    ccccc()
    return

The keyword defer is used to register deferred calls.

These calls are not executed until return. Therefore, it can be used for resource cleaning.

Multiple defer statements are executed in a first in and last out manner

The Convention is: use panic for irreparable errors in key processes and error for others.

func main() {
    test()
}

func test() {
    defer func() {
        if err := recover(); err != nil {
            println(err.(string)) // Transform the interface {} into a concrete type.
        }
    }()

    panic("panic error!")
}

expression

package main

import "fmt"

type User struct {
    id   int
    name string
}

func (self *User) Test() {
    fmt.Printf("%p, %v\n", self, self)
}

func main() {
    u := User{1, "Tom"}
    u.Test()

    mValue := u.Test
    mValue() // Implicit delivery receiver

    mExpression := (*User).Test
    mExpression(&u) // Explicitly pass receiver
}

Define error http://www.topgoer.com/%E6%96%B9%E6%B3%95/%E8%87%AA%E5%AE%9A%E4%B9%89error.html

//Return exception
package main

import (
   "errors"
   "fmt"
)

func getCircleArea(radius float32) (area float32, err error) {
   if radius < 0 {
      // Build an exception object
      err = errors.New("Radius cannot be negative")
      return
   }
   area = 3.14 * radius * radius
   return
}

func main() {
   area, err := getCircleArea(-5)
   if err != nil {
      fmt.Println(err)
   } else {
      fmt.Println(area)
   }
}

//System throw anomaly
package main

import "fmt"

func test01() {
   a := [5]int{0, 1, 2, 3, 4}
   a[1] = 123
   fmt.Println(a)
   //a[10] = 11
   index := 10
   a[index] = 10
   fmt.Println(a)
}

func getCircleArea(radius float32) (area float32) {
   if radius < 0 {
      // Throw yourself
      panic("Radius cannot be negative")
   }
   return 3.14 * radius * radius
}

func test02() {
   getCircleArea(-5)
}

//
func test03() {
   // Delay execution of anonymous functions
   // When is the delay? (1) The program ends normally (2) when an exception occurs
   defer func() {
      // Recover
      // Why did the program hang up
      if err := recover(); err != nil {
         fmt.Println(err)
      }
   }()
   getCircleArea(-5)
   fmt.Println("Is there any execution here")
}

func test04()  {
   test03()
   fmt.Println("test04")
}

func main() {
   test04()
}
//Custom error
package main

import (
    "fmt"
    "os"
    "time"
)

type PathError struct {
    path       string
    op         string
    createTime string
    message    string
}

func (p *PathError) Error() string {
    return fmt.Sprintf("path=%s \nop=%s \ncreateTime=%s \nmessage=%s", p.path,
        p.op, p.createTime, p.message)
}

func Open(filename string) error {

    file, err := os.Open(filename)
    if err != nil {
        return &PathError{
            path:       filename,
            op:         "read",
            message:    err.Error(),
            createTime: fmt.Sprintf("%v", time.Now()),
        }
    }

    defer file.Close()
    return nil
}

func main() {
    err := Open("/Users/5lmh/Desktop/go/src/test.txt")
    switch v := err.(type) {
    case *PathError:
        fmt.Println("get path error,", v)
    default:

    }

}

interface application

// Empty interface as function parameter
func show(a interface{}) {
    fmt.Printf("type:%T value:%v\n", a, a)
}

// Empty interface as map value
    var studentInfo = make(map[string]interface{})
    studentInfo["name"] = "Li Bai"
    studentInfo["age"] = 18
    studentInfo["married"] = false
    fmt.Println(studentInfo)

go schedule sync WaitGroup

var wg sync.WaitGroup

func hello(i int) {
    defer wg.Done() // Registration at the end of goroutine - 1
    fmt.Println("Hello Goroutine!", i)
}
func main() {

    for i := 0; i < 10; i++ {
        wg.Add(1) // Start a goroutine and register + 1
        go hello(i)
    }
    wg.Wait() // Wait for all registered goroutine s to end
}

go runtime.Gosched()

//Give up CPU time slice, Reschedule tasks (it probably means that you planned to go out for barbecue on a good weekend, but your mother asked you to go on a blind date. The first is that you are very fast on a blind date, and the meeting will not delay you to continue the barbecue. The second is that you are very slow on a blind date. The meeting is yours and mine, and you delay the barbecue, but if you are greedy, you have to go to barbecue if you delay the barbecue.)
package main

import (
    "fmt"
    "runtime"
)

func main() {
    go func(s string) {
        for i := 0; i < 2; i++ {
            fmt.Println(s)
        }
    }("world")
    // Main coordination process
    for i := 0; i < 2; i++ {
        // Cut it and assign the task again
        runtime.Gosched()
        fmt.Println("hello")
    }
}

runtime.Goexit()

//Quit the current cooperation process (I was on a blind date while having a barbecue. I suddenly found that the blind date was too ugly to affect the barbecue. I decided to let her go, and then there was no more)
package main

import (
    "fmt"
    "runtime"
)

func main() {
    go func() {
        defer fmt.Println("A.defer")
        func() {
            defer fmt.Println("B.defer")
            // End the process
            runtime.Goexit()
            defer fmt.Println("C.defer")
            fmt.Println("B")
        }()
        fmt.Println("A")
    }()
    for {
    }
}

runtime.GOMAXPROCS

//Go1. After version 5, all CPU logical cores are used by default
///Two tasks have only one logical core. At this time, it is to finish one task and then do another task. Set the number of logical cores to 2. At this time, the two tasks are executed in parallel. The code is as follows.
func a() {
    for i := 1; i < 10; i++ {
        fmt.Println("A:", i)
    }
}

func b() {
    for i := 1; i < 10; i++ {
        fmt.Println("B:", i)
    }
}

func main() {
    runtime.GOMAXPROCS(2)
    go a()
    go b()
    time.Sleep(time.Second)
}

passageway

1. Sending a value to a closed channel will cause panic.

2. Receiving a closed channel will obtain the value until the channel is empty.

3. Performing a receive operation on a closed channel with no value will get the corresponding type of zero value.

4. Closing a closed channel will cause panic.

5. Chan < - int is a channel that can only be sent, which can be sent but cannot be received;

6 < - Chan int is a channel that can only receive, but can not send.

func counter(out chan<- int) {
    for i := 0; i < 100; i++ {
        out <- i
    }
    close(out)
}

func squarer(out chan<- int, in <-chan int) {
    for i := range in {
        out <- i * i
    }
    close(out)
}
func printer(in <-chan int) {
    for i := range in {
        fmt.Println(i)
    }
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    go counter(ch1)
    go squarer(ch2, ch1)
    printer(ch2)
}

Channel use cases

type Job struct {
    Id      int
    RandNum int
}
type Result struct {
    job *Job
    sum int
}

func createPool(num int, jobChan chan *Job,resultChan chan *Result) {
    for i := 0; i < num; i++ {
        go func(jobChan chan *Job,resultChan chan *Result) {
            for i2 := range jobChan {
                r_num := i2.RandNum

                var sum int
                for r_num !=0 {
                    tmp := r_num % 10
                    sum += tmp
                    r_num /= 10
                }
                r := &Result{
                    job: i2,
                    sum: sum,
                }
                resultChan <- r
            }
        }(jobChan,resultChan)
    }
}

func main() {
    flag.Parse()

    jobChan := make(chan *Job, 128)
    resultChan := make(chan *Result, 128)
    createPool(64, jobChan, resultChan)
    // 4. Open a printing process
    go func(resultChan chan *Result) {
        // Traversal result pipeline printing
        for result := range resultChan {
            fmt.Printf("job id:%v randnum:%v result:%d\n", result.job.Id,
                result.job.RandNum, result.sum)
        }
    }(resultChan)
    var id int
    // Create a job in a loop and input it into the pipeline
    for {
        id++
        // Generate random number
        r_num := rand.Int()
        job := &Job{
            Id:      id,
            RandNum: r_num,
        }
        jobChan <- job
    }
    return
    }

select listening channel

    select {
    case <-chan1:
       // If chan1 successfully reads the data, the case processing statement is executed
    case chan2 <- 1:
       // If the data is successfully written to chan2, the case processing statement is executed
    default:
       // If none of the above is successful, enter the default process
    }

flag usage and OS args

   var name string
    var age int
    var married bool
    var delay time.Duration
    flag.StringVar(&name, "name", "Zhang San", "full name")
    flag.IntVar(&age, "age", 18, "Age")
    flag.BoolVar(&married, "married", false, "marriage ")
    flag.DurationVar(&delay, "d", 0, "Delay interval")
    Or use
    name := flag.String("name", "Zhang San", "full name")
    age := flag.Int("age", 18, "Age")
    married := flag.Bool("married", false, "marriage ")
    delay := flag.Duration("d", 0, "time interval")


    //Parsing command line parameters
    flag.Parse()
    fmt.Println(name, age, married, delay)
    //Return other parameters after command line parameters
    fmt.Println(flag.Args())
    //Returns the number of other parameters after the command line parameters
    fmt.Println(flag.NArg())
    //Returns the number of command line parameters used
    fmt.Println(flag.NFlag())


    //os.args
        if len(os.Args) > 0 {
        for index, arg := range os.Args {
            fmt.Printf("args[%d]=%v\n", index, arg)
        }
    }

Log file

    logFile, err := os.OpenFile("./smallsha.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
    if err != nil {
        fmt.Println("open log file failed, err:", err)
        return
    }
    log.SetOutput(logFile)  //Set log file write
    log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
    log.SetPrefix("[smallsha]")
    log.Printf("%s","smallsha")
    log.Println("test")
    //log.Panic("test1")
    //log.Fatalln("test2")

    logger := log.New(os.Stdout, "<New>", log.Lshortfile|log.Ldate|log.Ltime)
    logger.Println("This is custom logger Log of records.")

Cyclic operation

arr := [5]int{1,2,4,5,6,8}
for i,num :=range arr {
    fmt.Println(i,num)
}
//while for loop matching channel
    var (
        ch11 = make(chan int)
        ch12 = make(chan int)
    )

    go func() {
        for i := 0; i < 10; i++ {
            ch11 <- i
        }
        close(ch11)
    }()

    go func() {
        for {
            i, ok := <-ch11
            if !ok {
                break
            }
            ch12 <- i * i
        }
        close(ch12)
    }()

    for i := range ch12 {
         fmt.Println(i)
    }

Pointer

const MAX int =3
func main(){
    a :=[]int{1,3,5}
    var ptr [MAX]*int;
      for  i = 0; i < MAX; i++ {
      ptr[i] = &a[i] /* Assign integer address to pointer array */
   }

   for  i = 0; i < MAX; i++ {
      fmt.Printf("a[%d] = %d\n", i,*ptr[i] )
   }
}

strconv use

    s3, _ := strconv.ParseBool("1")
    fmt.Printf("%# v\n", pretty.Formatter(s3))
    return
    //int to string
    s2 := 100
    i2 := strconv.Itoa(s2)
    fmt.Printf("%# v\n", pretty.Formatter(i2))
    return
    //string to int
    s1 := "100"
    i1, err := strconv.Atoi(s1)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("%# v\n", pretty.Formatter(i1))
    return

template can be used to register http

package logic

import (
    "fmt"
    "html/template"
    "net/http"
)

func init() {
    http.HandleFunc("/",sayHello)
    err := http.ListenAndServe(":9090", nil)
    if err != nil {
        fmt.Println(err)
        return
    }
}
type UserInfo struct {
    Name   string
    Gender string
    Age    int
}

func sayHello(w http.ResponseWriter,r *http.Request)  {
    // Generate template object by parsing specified file
    tmpl, err := template.ParseFiles("./hello.html")
    if err != nil {
        fmt.Println("create template failed, err:", err)
        return
    }
    // Render the template with the given data and write the results to w
    user := UserInfo{
        Name:   "Withered vine",
        Gender: "male",
        Age:    18,
    }
    // Render the template with the given data and write the results to w
    tmpl.Execute(w, user)
}

Define structure

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}

func main() {
   var Book1 Books        /* Declare Book1 as a Books type */
   var Book2 Books        /* Declare Book2 as a Books type */

   /* book 1 describe */
   Book1.title = "Go language"
   Book1.author = "www.runoob.com"
   Book1.subject = "Go Language course"
   Book1.book_id = 6495407

   /* book 2 describe */
   Book2.title = "Python course"
   Book2.author = "www.runoob.com"
   Book2.subject = "Python Language course"
   Book2.book_id = 6495700

   /* Print Book1 information */
   printBook(&Book1)

   /* Print Book2 information */
   printBook(&Book2)
}
func printBook( book *Books ) {
   fmt.Printf( "Book title : %s\n", book.title)
   fmt.Printf( "Book author : %s\n", book.author)
   fmt.Printf( "Book subject : %s\n", book.subject)
   fmt.Printf( "Book book_id : %d\n", book.book_id)
}

//Structure new and assignment
 type Person struct {
    Username string `json:"username"`
    Password string `json:"password"`
}

//Declaration construction method
func newPerson(username string, password string) *Person {
    return &Person{
        Username: username,
        Password: password,
    }
}
//Defines how to modify the structure
func (p *Person) setUsername(username string) {
    p.Username = username
}


map operation

package main

import "fmt"

func main() {
    var countryCapitalMap map[string]string /*Create collection */
    countryCapitalMap = make(map[string]string)

    /* map Insert the key - value pair and the corresponding capital of each country */
    countryCapitalMap [ "France" ] = "Paris"
    countryCapitalMap [ "Italy" ] = "Rome"
    countryCapitalMap [ "Japan" ] = "Tokyo"
    countryCapitalMap [ "India " ] = "New Delhi"

    /*Use the key to output map values */
    for country := range countryCapitalMap {
        fmt.Println(country, "The capital is", countryCapitalMap [country])
    }

    /*Check whether the element exists in the collection */
    capital, ok := countryCapitalMap [ "American" ]
    /*Delete element*/ delete(countryCapitalMap, "France")
    /*If it is determined to be true, it exists, otherwise it does not exist */
    /*fmt.Println(capital) */
    /*fmt.Println(ok) */
    if (ok) {
        fmt.Println("American Our capital is", capital)
    } else {
        fmt.Println("American The capital of does not exist")
    }
}
Declare variable
    package main
    import "fmt"
    func main() {
        var a string = "Runoob"
        fmt.Println(a)

        var b, c int = 1, 2
        fmt.Println(b, c)
    }

Declaration method
    package main
    import "fmt"
    func swap(x, y string) (string, string) {
       return y, x
    }
    func main() {
       a, b := swap("Google", "Runoob")
       fmt.Println(a, b)
    }
Define array
    var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
    var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
    package main
    import "fmt"
    func main() {
       var n [10]int /* n Is an array with a length of 10 */
       var i,j int
       /* Initializing elements for array n */        
       for i = 0; i < 10; i++ {
          n[i] = i + 100 /* Set element to i + 100 */
       }
       /* Output the value of each array element */
       for j = 0; j < 10; j++ {
          fmt.Printf("Element[%d] = %d\n", j, n[j] )
       }
    }

Go language structure

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}

func main() {
   var Book1 Books        /* Declare Book1 as a Books type */
   var Book2 Books        /* Declare Book2 as a Books type */

   /* book 1 describe */
   Book1.title = "Go language"
   Book1.author = "www.runoob.com"
   Book1.subject = "Go Language course"
   Book1.book_id = 6495407

   /* book 2 describe */
   Book2.title = "Python course"
   Book2.author = "www.runoob.com"
   Book2.subject = "Python Language course"
   Book2.book_id = 6495700

   /* Print Book1 information */
   fmt.Printf( "Book 1 title : %s\n", Book1.title)
   fmt.Printf( "Book 1 author : %s\n", Book1.author)
   fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
   fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)

   /* Print Book2 information */
   fmt.Printf( "Book 2 title : %s\n", Book2.title)
   fmt.Printf( "Book 2 author : %s\n", Book2.author)
   fmt.Printf( "Book 2 subject : %s\n", Book2.subject)
   fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id)
}

Structure as function parameter
    func printBook( book Books ) {
       fmt.Printf( "Book title : %s\n", book.title)
       fmt.Printf( "Book author : %s\n", book.author)
       fmt.Printf( "Book subject : %s\n", book.subject)
       fmt.Printf( "Book book_id : %d\n", book.book_id)
    }

Declare the difference between functions and methods

#function
func main() {
    sum := add(1, 2)
    fmt.Println(sum)
}

func add(a, b int) int {
    return a + b
}
#method
type person struct {
    name string
}

func (p person) String() string{
    return "the person name is "+p.name
}

func main() {
    p:=person{name:"Zhang San"}
    fmt.Println(p.String())
}

#Variable parameter
func main() {
    print("1","2","3")
}

func print (a ...interface{}){
    for _,v:=range a{
        fmt.Print(v)
    }
    fmt.Println()
}

The modified string needs to be converted to byte or run first

func changeString() {
    s1 := "hello"
    // Cast type
    byteS1 := []byte(s1)
    byteS1[0] = 'H'
    fmt.Println(string(byteS1))

    s2 := "Blog"
    runeS2 := []rune(s2)
    runeS2[0] = 'dog'
    fmt.Println(string(runeS2))
}