Go语言学习笔记 | 青训营笔记

81 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第11天。笔记记录了Go语言重要特性。参考:books.studygolang.com/gobyexample…

  1. Slice
  • 不像数组,slice 的类型仅由它所包含的元素决定(不像数组中还需要元素的个数)。要创建一个长度非零的空slice,需要使用内建的方法 make。s := make([]string, 3)
  • s = append(s, "a")
  • c := make([]string, len(s)) cope(c,s)
  • 切片
  • Slice 可以组成多维数据结构。内部的 slice 长度可以不同,这和多位数组不同。
  1. map

当从一个 map 中取值时,可选的第二返回值指示这个键是在这个 map 中。这可以用来消除键不存在和键有零值,像 0 或者 "" 而产生的歧义。

  1. range

for index , value := range nums for key:value := range maps

  1. 函数-多值返回

Go 内建多返回值 支持。这个特性在 Go 语言中经常被用到,例如用来同时返回一个函数的结果和错误信息。

空白定义符:_, c := add (a+b)

  1. 函数-变参函数

可以使用任意数量的参数调用

    
func sum(nums ...int) {
    fmt.Print(nums, " ")
    total := 0
    for _, num := range nums {
        total += num
    }
    fmt.Println(total)
}
如果你的 slice 已经有了多个值,想把它们作为变参使用,你要这样调用 func(slice...)
  1. 闭包

闭包:就是能够读取其他函数内部变量的函数。将函数内部与外部连接起来

  1. 指针

表示: *int; 解引用: *ipter; 取地址符: &i

  1. 结构体

& 前缀生成一个结构体指针,使用.访问结构体字段,指针会被自动解引用

  1. 接口

接口是方法特征的命名集合。

接口是一种类型。

如果一个变量的是接口类型,那么我们可以调用这个被命名的接口中的方法。这里有一个一通用的 measure 函数,利用这个特性,它可以用在任何 geometry 上。

type geometry interface {
    area() float64
    perim() float64
}
  1. 错误处理
  • errors.New 构造一个使用给定的错误信息的基本error 值。

  • 按照惯例,错误通常是最后一个返回值并且是 error 类型,一个内建的接口。

  • 返回错误值为 nil代表没有错误。

    普遍用法:

    if r, e := f2(i); e != nil {
                fmt.Println("f2 failed:", e)
            } else {
                fmt.Println("f2 worked:", r)
           }
    

    11.协程和通道

  • 使用 go f(s) 在一个 Go 协程中调用这个函数。这个新的 Go 协程将会并行的执行这个函数调用。

  • 通道 是连接多个 Go 协程的管道。你可以从一个 Go 协程将值发送到通道,然后在别的 Go 协程中接收。

    • 使用 make(chan val-type) 创建一个新的通道。通道类型就是他们需要传递值的类型。
    • 使用 channel <- 语法 发送 一个新的值到通道中。
    • 使用 <-channel 语法从通道中 接收 一个值。
    • 默认发送和接受操作是阻塞的,不用使用同步操作。
    • 通道缓冲messages := make(chan string, 2)
    • 通道方向:可以指定这个通道是不是只用来发送或者接收值。
    • 通道选择器select,同时等待多通道的值,select 默认处理第一个已准备好的接收操作。<-Time.After作为超时case
    • 非阻塞通道:使用带一个 default 子句的 select 来实现非阻塞 的发送、接收,甚至是非阻塞的多路 select
    • 关闭通道:使用 j, more := <- jobs 循环的从jobs 接收数据。在接收的这个特殊的二值形式的值中,如果 jobs 已经关闭了,并且通道中所有的值都已经接收完毕,那么 more 的值将是 false。当我们完成所有的任务时,将使用这个特性通过 done 通道去进行通知。
    • 通道遍历:使用for range, 如果我们没有 close 它,我们将在这个循环中继续阻塞执行,等待接收第三个值

    12.defer

    Defer 被用来确保一个函数调用在程序执行结束前执行。同样用来执行一些清理工作。

    13.JSON

    var dat map[string]interface{}
    

我们需要提供一个 JSON 包可以存放解码数据的变量。这里的 map[string]interface{} 将保存一个 string 为键,值为任意值的map。

if err := json.Unmarshal(byt, &dat); err != nil {
        panic(err)
    }
    fmt.Println(dat)