ok判别式

2023-06-18 11:02:30 浏览数 (1)

类似

代码语言:javascript复制
if _, ok := map[key]; ok {
//存在
}

这样的编译器简化后的判断代码(实际应该是一种语法糖),在Go中非常常用. 一般称为称 "ok判别式"。当然这个变量的名称可以随意取,不一定是"ok"

检测map中是否存在某个key

代码语言:javascript复制
package main

import "fmt"

func main() {

    isVip := make(map[string]bool)

    isVip["张三"] = true
    isVip["李四"] = false

    if val, ok := isVip["王五"]; ok {
        fmt.Printf("王五是否为vip:%tn", val)
    } else {
        fmt.Println("王五不是注册用户")
    }

    if val, ok := isVip["李四"]; ok {
        fmt.Printf("李四是否为vip:%tn", val)
    } else {
        fmt.Println("李四不是注册用户")
    }

}

输出为:

代码语言:javascript复制
王五不是注册用户
李四是否为vip:false

类型断言:检测一个接口类型的变量i,是否包含了类型T

代码语言:javascript复制
if value, ok := i.(T); ok {
    fmt.Println(value)
} else{
 // 接口类型i没有包含类型T
}

更多可参见:

[Golang类型断言]()


检测一个通道是否关闭

更确切说,实际是检测一个通道还能否继续读取.

即对于有缓存的通道ch,在close(ch)之后,如果还有未读取出的变量,ok判别式的值为true.

即改为: 检测一个通道能否继续读取更为合适


检测是否还能从通道中读取出传递的值

代码语言:javascript复制
package main

import "fmt"

func main() {

    ch := make(chan int, 2)

    fmt.Println(ch)

    ch <- 271828

    fmt.Println(<-ch) //这样也相当于进行了读取,channel里的缓存空间又会增加1个单位

    ch <- 271828  //#1
    ch <- 271828 //#2

    //channel<-271828 //如果继续写入,超过缓存值2,则会报fatal error: all goroutines are asleep - deadlock!

    close(ch)

    //关闭之后尝试进行读取
    //channel关闭之后,仍然可以从channel中读取剩余的数据,直到数据全部读取完成。
    //读取完后继续读,得到的将是对应类型的零值.

    if val, ok := <-ch; ok {
        fmt.Println("值为:", val)
    } else {
        fmt.Println("通道已被关闭,无法再进行读取")
    }

}

输出为i:

代码语言:javascript复制
0xc00009a000
271828
值为: 271828

而如果将两行写缓存的代码注释掉,即注释掉#1和#2,则输出结果为:

代码语言:javascript复制
0xc000090000
271828
通道已被关闭,无法再进行读取

即如果还能读出缓存的值,即便通道已经被关闭,ok的值依然会是true

0 人点赞