类似
代码语言: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