

6. Go语言中的字典与布尔类型
source link: https://studygolang.com/articles/27664
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

文章首发自公众号:Go编程时光
《Go编程时光》,一个能带你学习 Go 语言的专栏,同时欢迎搜索我的同名公众号【Go编程时光】(排版精美更适合阅读),第一时间获取Go语言干货。
系列导读
1. 字典
字典(Map 类型),是由若干个 key:value
这样的键值对映射组合在一起的数据结构。
它是哈希表的一个实现,这就要求它的每个映射里的key,都是唯一的,可以使用 ==
和 !=
来进行判等操作,换句话说就是key必须是可哈希的。
什么叫可哈希的?简单来说,一个不可变对象,都可以用一个哈希值来唯一表示,这样的不可变对象,比如字符串类型的对象(可以说除了切片、 字典,函数之外的其他内建类型都算)。
意思就是,你的 key 不能是切片,不能是字典,不能是函数。。
字典由key和value组成,它们各自有各自的类型。
在声明字典时,必须指定好你的key和value是什么类型的,然后使用 map 关键字来告诉Go这是一个字典。
map[KEY_TYPE]VALUE_TYPE 复制代码
声明初始化字典
三种声明并初始化字典的方法
// 第一种方法 var scores map[string]int = map[string]int{"english": 80, "chinese": 85} // 第二种方法 scores := map[string]int{"english": 80, "chinese": 85} // 第三种方法 scores := make(map[string]int) scores["english"] = 80 scores["chinese"] = 85 复制代码
要注意的是,第一种方法如果拆分成多步(声明、初始化、再赋值),和其他两种有很大的不一样了,相对会比较麻烦。
import "fmt" func main() { // 声明一个名为 score 的字典 var scores map[string]int // 未初始化的 score 的零值为nil,无法直接进行赋值 if scores == nil { // 需要使用 make 函数先对其初始化 scores = make(map[string]int) } // 经过初始化后,就可以直接赋值 scores["chinese"] = 90 fmt.Println(scores) } 复制代码
字典的相关操作
添加元素
scores["math"] = 95 复制代码
更新元素,若key已存在,则直接更新value
scores["math"] = 100 复制代码
读取元素,直接使用 [key]
即可 ,如果 key 不存在,也不报错,会返回其value-type 的零值。
fmt.Println(scores["math"]) 复制代码
删除元素,使用 delete 函数,如果 key 不存在,delete 函数会静默处理,不会报错。
delete(scores, "math") 复制代码
当访问一个不存在的key时,并不会直接报错,而是会返回这个 value 的零值,如果 value的类型是int,就返回0。
package main import "fmt" func main() { scores := make(map[string]int) fmt.Println(scores["english"]) // 输出 0 } 复制代码
判断 key 是否存在
当key不存在,会返回value-type的零值 ,所以你不能通过返回的结果是否是零值来判断对应的 key 是否存在,因为 key 对应的 value 值可能恰好就是零值。
其实字典的下标读取可以返回两个值,使用第二个返回值都表示对应的 key 是否存在,若存在ok为true,若不存在,则ok为false
import "fmt" func main() { scores := map[string]int{"english": 80, "chinese": 85} math, ok := scores["math"] if ok { fmt.Printf("math 的值是: %d", math) } else { fmt.Println("math 不存在") } } 复制代码
我们将上面的代码再优化一下
import "fmt" func main() { scores := map[string]int{"english": 80, "chinese": 85} if math, ok := scores["math"]; ok { fmt.Printf("math 的值是: %d", math) } else { fmt.Println("math 不存在") } } 复制代码
如何对字典进行循环
Go 语言中没有提供类似 Python 的 keys() 和 values() 这样方便的函数,想要获取,你得自己循环。
循环还分三种
- 获取 key 和 value
import "fmt" func main() { scores := map[string]int{"english": 80, "chinese": 85} for subject, score := range scores { fmt.Printf("key: %s, value: %d\n", subject, scores) } } 复制代码
- 只获取key,这里注意不用占用符。
import "fmt" func main() { scores := map[string]int{"english": 80, "chinese": 85} for subject := range scores { fmt.Printf("key: %s\n", subject) } } 复制代码
- 只获取 value,用一个占位符替代。
import "fmt" func main() { scores := map[string]int{"english": 80, "chinese": 85} for _, score := range scores { fmt.Printf("value: %d\n", score) } } 复制代码
2. 布尔类型
关于布尔值,无非就两个值:true 和 false。只是这两个值,在不同的语言里可能不同。
在 Python 中,真值用 True 表示,与 1 相等,假值用 False 表示,与 0 相等
>>> True == 1 True >>> False == 0 True >>> 复制代码
而在 Go 中,真值用 true 表示,不但不与 1 相等,并且更加严格,不同类型无法进行比较,而假值用 false 表示,同样与 0 无法比较。
如下图所示,Goland 直接波浪线提示类型不匹配,不能比较。

Go 中确实不如 Python 那样灵活,bool 与 int 不能直接转换,如果要转换,需要你自己实现函数。
bool 转 int
func bool2int(b bool) int { if b { return 1 } return 0 } 复制代码
int 转 bool
func int2bool(i int) bool { return i != 0 } 复制代码
在 Python 中使用 not 对逻辑值取反,而 Go 中使用 !
符号
import "fmt" var male bool = true func main() { fmt.Println( !male == false) // 或者 fmt.Println( male != false) } // output: true 复制代码
一个 if 判断语句,有可能不只一个判断条件,在 Python 中是使用 and
和 or
来执行逻辑运算
>>> age = 15 >>> gender = "male" >>> >>> gender == "male" and age >18 False 复制代码
而在 Go 语言中,则使用 &&
表示 且
,用 ||
表示 或
,并且有短路行为(即左边表达式已经可以确认整个表达式的值,那么右边将不会再被求值。
import "fmt" var age int = 15 var gender string = "male" func main() { // && 两边的表达式都会执行 fmt.Println( age > 18 && gender == "male") // gender == "male" 并不会执行 fmt.Println( age > 18 || gender == "male") } // output: false // output: true 复制代码

Recommend
-
44
文章目录 [隐藏] 新年第一更!之前群友问了一个C语言问题,即int(*(*p)())、int *(*p)()和int *(*p())的区别在哪里。确实,有时C语言的类型声明是很魔性的,看着也很令人头疼。不过如果拆分开来看其实还挺好...
-
44
-
28
Go语言中[]byte和string类型相互转换时的性能分析和优化 2019-07-01 | Go我们在使用Go语言时,经常涉及到[]byte和string两种类型间的转换。本篇文章将讨论转换...
-
59
常量 常量声明 常量是程序在编译时就确定的值,程序在执行时不能修改常量的值。声明常量使用关键字const。在声明常量时,需要对常量赋值。 const 名称 类型 = 值 或 const 名称 = 值 自动做类型...
-
28
Hi,大家好。 我是明哥,在自己学习 Golang 的这段时间里,我写了详细的学习笔记放在我的个人微信公众号 《Go编程时光》,对于 Go 语言,我也算是个初学者,因此写的东西应该会比较适合刚接触的同学,如果你也是刚学习 Go 语言,...
-
18
Hi,大家好,我是明哥。 在自己学习 Golang 的这段时间里,我写了详细的学习笔记放在我的个人微信公众号 《Go编程时光》,对于 Go 语言,我也算是个初学者,因此写的东西应该会比较适合刚接触的同学,如果你也是刚学习 Go 语言,不...
-
25
他的胡言乱语竟有方法自圆其说。 —— 莎士比亚,《哈姆雷特》 数十年以来, 传统的面向对象语言总是说方法属于类, 但 Go 不是这样做的: 它提供了方法,...
-
7
在 Go 语言中通过方法为类型添加行为¶ 他的胡言乱语竟有方法自圆其说。 —— 莎士比亚,《哈姆雷特》
-
8
C语言程序开发是离不开条件判断语句的,有程序员甚至认为编程其实就是 if else 再加上一点数学计算。不过,对于计算机来说,条件判断结果只有两个可能值:真 或者 假。C语言认为所有非零值都是“真”,零值为“假”,虽然很简单,但是从读...
-
3
当我们使用System.Text.Json.JsonSerializer对一个字典对象进行序列化的时候,默认情况下字典的Key不能是一个自定义的类型,本文介绍几种解决方案。一、问题重现 二、自定义JsonConverter能解决吗? 三、自定义TypeConverter能解决问...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK