【學習】分享幾個學習中的小問題

icecho發表於2019-09-19

defer 關鍵字

以下是一個簡單的小 demo

package main

import "fmt"

func main() {
    defer fmt.Println(1)

    defer fmt.Println(2)

    defer fmt.Println(3)

    panic("error!")
}

// 3
// 2
// 1
// panic:error!

程式遇到 panic 時,會先依次執行 defer 然後再將 panic 傳遞出去。

for 迴圈中的臨時變數

還是以一個小 demo 來練習

package main

import "fmt"

type student struct {
    Name string
    Age  int
}

func initStudents() map[string]*student {
    m := make(map[string]*student)

    students := []student{
        {Name: "jack", Age: 24},
        {Name: "rose", Age: 23},
        {Name: "wang", Age: 22},
    }

    for _, student := range students {
        m[student.Name] = &student
    }

    return m
}
func main() {
    students := initStudents()

    for k, v := range students {
        fmt.Println(k, *v)
    }
}

// rose {wang 22}
// wang {wang 22}
// jack {wang 22}

for 迴圈遍歷時,student 是一個臨時變數,遍歷過程中,在記憶體中的地址不變,賦值都是指向了同一個記憶體區域,導致後面的值其實都是一樣的。

在 goroutine 中列印

package main

import (
    "fmt"
    "sync"
)

func main() {
    wg := sync.WaitGroup{}
    wg.Add(5)
    for i := 0; i < 5; i++ {
        go func() {
            fmt.Println("i: ", i)
            wg.Done()
        }()
    }
    wg.Wait()
}

// 5
// 5
// 5
// 5
// 5

在 go 關鍵字後建立了一個匿名函式,同時它也是一個閉包,程式碼塊中的 i 是對外部變數 i 的引用,go 關鍵字開啟 goroutine 執行閉包,意味著它不會順序執行,一般等該程式碼片段被排程器執行的時候,for 迴圈已經退出,此時 i 為 5,所以會在控制檯列印出 5 個 5。

結構體組合

package main

import "fmt"

type People struct{}

func (p *People) ShowA() {

    fmt.Println("showA")

    p.ShowB()
}

func (p *People) ShowB() {

    fmt.Println("showB")

}

type Teacher struct {
    People
}

func (t *Teacher) ShowB() {
    fmt.Println("teacher showB")
}

func main() {
    t := Teacher{}
    t.ShowA()
    t.ShowB()
}

// showA
// showB
// teacher showB

go 中沒有繼承,只有組合,Teacher 中的 People 是一個匿名物件,通過它呼叫的函式都是自身的。

Hello。

相關文章