Go 语言小细节(一)


多个 defer 出现的时候,多个 defer 之间按照 LIFO(后进先出)的顺序执行

package main
import "fmt"
func main(){
    defer func(){
        fmt.Println("1")
    }()
    defer func(){
        fmt.Println("2")
    }()
    defer func(){
        fmt.Println("3")
    }()
}

对应的输出是:

3
2
1

用 for range 来遍历数组或者 map 的时候,被遍历的指针是不变的,每次遍历仅执行 struct 值的拷贝

import "fmt"

type student struct{
    Name string
    Age  int
}

func main(){
    var stus []student
    stus = []student{
        {Name:"one", Age: 18},
        {Name:"two", Age: 19},
    }
    data := make(map[int]*student)
    for i, v := range stus{
        data[i] = &v   //应该改为:data[i] = &stus[i]
    }
    for i, v := range data{
        fmt.Printf("key=%d, value=%v \n", i,v)
    }
}

所以,结果输出为:

key=0, value=&{two 19}
key=1, value=&{two 19}

Go 中没有继承,叫组合

import "fmt"

type student struct{
    Name string
    Age  int
}

type boy struct {
    student
}

func (p *student) love(){
    fmt.Println("love")
}

func (p *student) like(){
    fmt.Println("like first")
    p.love()
}

func (b * boy) love(){
    fmt.Println("hate")
}

func main(){
    b := boy{}
    b.like()
}

输出:

like first
love

没有“对象”

package main

import (
    "fmt"
)

type test struct {
    name string
}

func (t *test) getName(){
    fmt.Println("hello world")
}

func main() {
    var t *test
    t = nil
    t.getName()
}

输出为:

hello world

Go 本质上不是面向对象的语言,Go 中是不存在 object 的含义的,Go 语言书籍中的对象也和 Java、PHP 中的对象有区别,不是真正的”对象”,是 Go 中 struct 的实体。

map 引用不存在的 key,不报错

import (
    "fmt"
)

func main(){
    newMap := make(map[string]int)
    fmt.Println(newMap["a"])
}

答案是:

0

map 使用 range 遍历顺序问题,并不是录入的顺序,而是随机顺序

import (
    "fmt"
)

func main(){
    newMap := make(map[int]int)
    for i := 0; i < 10; i++{
        newMap[i] = i
    }
    for key, value := range newMap{
        fmt.Printf("key is %d, value is %d\n", key, value)
    }
}

输出:

key is 1, value is 1
key is 3, value is 3
key is 5, value is 5
key is 7, value is 7
key is 9, value is 9
key is 0, value is 0
key is 2, value is 2
key is 4, value is 4
key is 6, value is 6
key is 8, value is 8

map 的遍历顺序不固定,这种设计是有意为之的,能为能防止程序依赖特定遍历顺序。

一个函数在将 channel 作为一个类型的参数来声明的时候,可以将 channl 声明为只可以取值(<- chan)或者只可以发送值(chan <-),不特殊说明,则既可以取值,也可以发送值。
只可以发送值

func setData(ch chan <- string){
    ...
}

如果在以上函数中存在 <-ch 则会编译不通过。

如下是只可以取值:

func setData(ch <- chan  string){
    ...
}

如果以上函数中存在 ch<- 则在编译期会报错。

分享:

评论