Skip to content

在 Go 语言中,comma ok(逗号ok)惯用法是一种用于判断操作是否成功的常用模式。它经常出现在类型断言、map 查找和通道接收等场景中。

类型断言中的 comma ok ​

当从接口类型断言为具体类型时,可以使用 comma ok 来判断断言是否成功。

go
package main

import "fmt"

func main() {
    var i interface{} = "hello"

    // 断言成功
    if s, ok := i.(string); ok {
        fmt.Println("string value:", s)
    } else {
        fmt.Println("not a string")
    }

    // 断言失败
    if n, ok := i.(int); ok {
        fmt.Println("int value:", n)
    } else {
        fmt.Println("not an int")
    }
}

输出:

string value: hello
not an int

ok 为 true 时拿到的是断言后的具体类型值,false 时值是零值,程序走 else 分支。

Map 查找中的 comma ok ​

在从 map 中查找键值对时,可以使用 comma ok 惯用法来判断键是否存在。

go
package main

import "fmt"

func main() {
    m := map[string]int{"a": 1, "b": 2}

    // 查找存在的键
    if value, ok := m["a"]; ok {
        fmt.Println("Found value:", value)
    } else {
        fmt.Println("Key not found")
    }

    // 查找不存在的键
    if value, ok := m["c"]; ok {
        fmt.Println("Found value:", value)
    } else {
        fmt.Println("Key not found")
    }
}

输出:

Found value: 1
Key not found

直接 m["c"] 拿到的零值没法区分"键不存在"和"值本身就是 0",加了 ok 就能把两种情况分开。

通道接收中的 comma ok ​

在从通道接收值时,可以使用 comma ok 惯用法来判断通道是否关闭。

go
package main

import (
    "fmt"
)

func main() {
    ch := make(chan int, 1)
    ch <- 1
    close(ch)

    // 从通道接收值
    if value, ok := <-ch; ok {
        fmt.Println("Received value:", value)
    } else {
        fmt.Println("Channel closed")
    }

    // 再次从已关闭的通道接收值
    if value, ok := <-ch; ok {
        fmt.Println("Received value:", value)
    } else {
        fmt.Println("Channel closed")
    }
}

输出:

Received value: 1
Channel closed

已关闭的通道再接收不会阻塞,零值配上 ok == false,就是"通道关了"的信号。

总结 ​

comma ok 惯用法是 Go 语言中一种常见的编程模式,用于判断某些操作是否成功。它主要用于以下场景:

  1. 类型断言:判断接口类型断言是否成功。
  2. Map 查找:判断键是否在 map 中存在。
  3. 通道接收:判断通道是否关闭。

三种场景共用一个写法:左边拿值,右边 ok 判成败,省掉了先查存在性再取值的两步,也避开了零值歧义。

参考资料 ​

同层页面 ​

相关页面 ​

Hello Golang