學(xué)習(xí)golang過程中遇到的坑

defer與panic

func中defer是隊列形式存儲的,panic執(zhí)行后面的defer不加入隊列

package main

import (
    "fmt"
)

func main() {
    defer_call()
}

func defer_call() {
    defer func() { fmt.Println("打印前") }()
    defer func() { fmt.Println("打印中") }()
    defer func() { fmt.Println("打印后") }()

    panic("觸發(fā)異常")
}

range 重用地址

range 循環(huán),會重用地址,也就是說,for _, stu := range stus 中的 stu 總是在同一個地址

type student struct {
    Name string
    Age  int
}

func pase_student() {
    m := make(map[string]*student)
    stus := []student{
        {Name: "zhou", Age: 24},
        {Name: "li", Age: 23},
        {Name: "wang", Age: 22},
    }
    for _, stu := range stus {
        m[stu.Name] = &stu
    }
}

select里面的case條件是隨機性的

func main() {
    runtime.GOMAXPROCS(1)
    int_chan := make(chan int, 1)
    string_chan := make(chan string, 1)
    int_chan <- 1
    string_chan <- "hello"
    select {
    case value := <-int_chan:
        fmt.Println(value)
    case value := <-string_chan:
        panic(value)
    }
}

defer的匿名函數(shù)參數(shù)是拷貝地址的(如果是指針就是最后指針的值),而函數(shù)里面的函數(shù)是優(yōu)先在main函數(shù)體中執(zhí)行的

func calc(index string, a, b int) int {
    ret := a + b
    fmt.Println(index, a, b, ret)
    return ret
}

func main() {
    a := 1
    b := 2
    defer calc("1", a, calc("10", a, b))
    a = 0
    defer calc("2", a, calc("20", a, b))
    b = 1
}

append 是往后面追加數(shù)據(jù)

func main() {
    s := make([]int, 5)
    s = append(s, 1, 2, 3)
    fmt.Println(s) // 輸出 0 0 0 0 0 1 2 3
}

interface接口 不通的對象類型對應(yīng)了不同的方法集,從而影響interface接口實現(xiàn)的對象

Methods Receivers         Values
-----------------------------------------------
(t T)                     T and *T

(t *T)                    *T 
package main

import (
    "fmt"
)

type People interface {
    Speak(string) string
}

type Stduent struct{}

func (stu *Stduent) Speak(think string) (talk string) {
    if think == "bitch" {
        talk = "You are a good boy"
    } else {
        talk = "hi"
    }
    return
}

func main() {
    var peo People = Stduent{}
    think := "bitch"
    fmt.Println(peo.Speak(think)) //指針類型的receiver 方法實現(xiàn)接口時,只有指針類型的對象實現(xiàn)了該接口 需要改成var peo People = &Stduent{}
}

nil類型的type vaule都是nil 而interface的nil數(shù)據(jù)結(jié)構(gòu)不一樣

package main

import (
    "fmt"
)

type People interface {
    Show()
}

type Student struct{}

func (stu *Student) Show() {

}

func live() People {
    var stu *Student
    return stu
}

func main() {
    if live() == nil {
        fmt.Println("AAAAAAA")
    } else {
        fmt.Println("BBBBBBB")  //輸出的時BBB
    }
}

append函數(shù)實現(xiàn)原理

1. 如果nums的cap夠用,則會直接在nums指向的數(shù)組后面追加元素,返回的slice和原來的slice是同一個對象。顯然,這種情況下原來的slice的值會發(fā)生變化! 
2. 如果nums的cap不夠用(上述代碼就是這種情況),則會重新分配一個數(shù)組空間用來存儲數(shù)據(jù),并且返回指向新數(shù)組的slice。這時候原來的slice指向的數(shù)組并沒有發(fā)生任何變化! 
3. 當(dāng)然,在任何情況下,返回的結(jié)果都是追加之后的slice,這一點沒有問題!
package main

import (
    "fmt"
)

func main() {
    x := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    fmt.Println(append(x[:5], x[6:]...), x) //x:1 2 3 4 5 7 8 9 10 10
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容