继数组array、切片slice和指针(pointer)、结构体(struct)之后,继续Go的复合类型。
字典(map)
Go的字典类型类似于Java的Map,python的Dictionary,都是一种无序的键值对的集合。可以通过键(key)来检索数据。
先看一个例子:
package main
import "fmt"
func main() {
map1 := map[string]string{"1": "s"}
fmt.Println("map1:", map1)
map1["1"] = "www"
fmt.Println("map1:", map1)
var map2 map[string]string
map2 = make(map[string]string)
fmt.Println("map2:", map2)
map2["1"] = "s"
fmt.Println("map2:", map2)
str, ok := map1["1"]
if ok {
fmt.Println("str:", str)
}
}
这个简单的例子基本上包含了map的基本用法,包括声明,赋值,取值等。
声明,初始化
单是map的声明和其他类型的变量声明类似。
var map_variable map[keytype]valuetype
//声明 一个map类型的变量,key和value的类型是string
var map2 map[string]string
单是声明map变量如果不初始化map的话,那么就会创建一个 nil map,默认值是 nil。nil map不能用来存放键值对。
package main
import "fmt"
func main() {
var myMap map[string]string
fmt.Println(myMap == nil)
myMap["1"] = "11"
fmt.Println("myMap:", myMap)
}
初始化的方法也有两种,可以直接初始化或者使用Go语言内置的函数make()来创建一个新map,这个和切片基本一样。
//定义是初始化赋值
map1 := map[string]string{"1": "s"}
//使用make函数初始化
var map2 map[string]string
map2 = make(map[string]string)
元素赋值和修改
赋值过程非常简单明了,就是将键和值用下面的方式对应起来即可:
map2["1"] = "s"
这样就给map类型的变量map2的key值为1的kery赋值为s。
通过上面的程序执行结果可以看出,如果key值已存在会更新key对应的值;若key不存在,则会早map里增加key值,并赋值。
元素查找
Go中,查找map中是否存在某个值是通过双赋值检测某个键是否存在。
vlaue, ok := map[key]
若key在map中,ok 为true;否则,ok 为false 。
若key不存在,那么vlaue 是该map元素类型的默认值。即如果map的value对应类型的默认值。
同样的,当从map中读取某个不存在的键时,结果是map的元素类型的默认值。
这样判断是否成功找到特定的键,不需要检查取到的值是否为nil,只需查看第二个返回值ok,代码表达更简洁。
元素删除
对于map元素的删除,Go提供了一个内置函数delete()。
delete(myMap, "1")
这样就把myMap中键为“1”的键值对删除。如果“1”这个键不存在,那么这个调 用将什么都不发生。
package main
import "fmt"
func main() {
myMap := map[string]string{"1": "a", "2": "b"}
fmt.Println("myMap:", myMap)
delete(myMap, "1")
fmt.Println("myMap:", myMap)
delete(myMap, "3")
fmt.Println("myMap:", myMap)
}
其他类型
一下类型只做概念性介绍,因为涉及的东西比较深入,目前我也是初学,体会不出太深刻的东西。
通道(chan)
通道是连接并发够程的管道。并发编程是个很大的论题,因此这里只是大致说一点,希望可以以此看出Go在并发编程里的优势。详细的内容,需要在以后使用中慢慢了解。
在并发编程中,为实现对共享变量的正确访问需要精确的控制,这在多数环境下都很困难。 Go语言另辟蹊径,它将共享的值通过信道传递,实际上,多个独立执行的线程从不会主动共享。 在任意给定的时间点,只有一个Go程能够访问该值。数据竞争从设计上就被杜绝了。 为了提倡这种思考方式,Go将它简化为一句口号:
不要通过共享内存来通信,而应通过通信来共享内存。
Go程的概念:Go程在多线程操作系统上可实现多路复用,因此若一个线程阻塞,比如说等待I/O, 那么其它的线程就会运行。Go程的设计隐藏了线程创建和管理的诸多复杂性。
在函数或方法前添加 go 关键字能够在新的Go程中调用它。当调用完成后, 该Go程也会安静地退出。有点像Unix Shell中的 & 符号,它能让命令在后台运行。
接口(interface)
对于接口的概念Go应该也其他支持接口的编程语言差别不大。
Go中的接口为指定对象的行为提供了一种方法:如果某样东西可以完成这个, 那么它就可以用在这里。
若某种现有的类型仅实现了一个接口,且除此之外并无可导出的方法,则该类型本身就无需导出。 仅导出该接口能让我们更专注于其行为而非实现,其它属性不同的实现则能镜像该原始类型的行为。
错误类型(error)
错误处理应该是任何编程语言都该涉及好的功能,Go也不例外。
Go语言的多值返回特性, 使得它在返回常规的值时,还能轻松地返回详细的错误描述。按照约定,错误的类型通常为 error,这是一个内建的简单接口。
type error interface {
Error() string
}
可以轻松实现这个接口以实现这样不仅能看见错误, 还能提供一些上下文。
有疑问加站长微信联系(非本文作者)