14

6. Go语言中的字典与布尔类型

 4 years ago
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. 一文搞定Go语言开发环境的搭建

2. Go 语言中五种变量创建的方法

3. Go语言中的整型与浮点型

4. Go语言中byte、rune与字符串区别?

5. 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() 这样方便的函数,想要获取,你得自己循环。

循环还分三种

  1. 获取 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)
	}
}
复制代码
  1. 只获取key,这里注意不用占用符。
import "fmt"

func main() {
	scores := map[string]int{"english": 80, "chinese": 85}

	for subject := range scores {
		fmt.Printf("key: %s\n", subject)
	}
}
复制代码
  1. 只获取 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 直接波浪线提示类型不匹配,不能比较。

ARv6NzM.png!web

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 中是使用 andor 来执行逻辑运算

>>> 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
复制代码
nIziIbE.png!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK