From c7a57c7dc47b3bde3fea2779d1c33c78bfea50d3 Mon Sep 17 00:00:00 2001 From: Tinywan <756684177@qq.com> Date: Tue, 7 Aug 2018 21:44:58 +0800 Subject: [PATCH] =?UTF-8?q?15=20-=20=E6=8C=87=E9=92=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/golang_tutorial_15.md | 452 +++++++++++++++++++++++++++++++++++ images/pointer-explained.png | Bin 0 -> 17563 bytes 2 files changed, 452 insertions(+) create mode 100644 docs/golang_tutorial_15.md create mode 100644 images/pointer-explained.png diff --git a/docs/golang_tutorial_15.md b/docs/golang_tutorial_15.md new file mode 100644 index 0000000..f3c65ce --- /dev/null +++ b/docs/golang_tutorial_15.md @@ -0,0 +1,452 @@ + +15 - 指针 +======================== + +上一节:[第十篇 if else 语句](/docs/golang_tutorial_10.md) +下一节:[第十二篇 包](/docs/golang_tutorial_12.md) + +这是本Golang系列教程的第15篇。 + +## 什么是指针? + +指针是存储一个变量的内存地址的变量。 + +![pointer-explained](../images/pointer-explained.png) + +在上图中,变量 `b` 的值是 `156`,存储在地址为 `0x1040a124` 的内存中。变量 `a` 存储了变量 `b` 的地址。现在可以说 `a` 指向 `b`。 + +## 指针的声明 + +指向类型 `T` 的指针用 `*T` 表示。 + +让我们写一些代码。 +```golang +package main + +import ( + "fmt" +) + +func main() { + b := 255 + var a *int = &b + fmt.Printf("Type of a is %T\n", a) + fmt.Println("address of b is", a) +} +``` + +`&` 操作符用来获取一个变量的地址。在上面的程序中,第 9 行我们将 `b` 的地址赋给 `a`(`a` 的类型为 `*int`)。现在我们说 `a` 指向了 `b`。当我们打印 `a` 的值时,`b` 的地址将会被打印出来。程序的输出为: +``` +Type of a is *int +address of b is 0x1040a124 +``` + +你可能得到的是一个不同的 `b` 的地址,因为 `b` 可以在内存中的任何地方。 + +## 指针的空值 + +指针的空值为 nil 。 + +```golang +personSalary := make(map[string]int) +``` + +上面的代码创建了一个名为 `personSalary` 的 map。其中键的类型为 string,值的类型为 int。 + +**map 的 0 值为 `nil`。试图给一个 nil map 添加元素给会导致运行时错误。因此 map 必须通过 make 来初始化** (译者注:也可以使用速记声明来创建 map,见下文)。 + +```golang +package main + +import ( + "fmt" +) + +func main() { + var personSalary map[string]int + if personSalary == nil { + fmt.Println("map is nil. Going to make one.") + personSalary = make(map[string]int) + } +} +``` + +上面的程序中,`personSalary` 为 `nil`,因此使用 make 初始化它。程序的输出为:`map is nil. Going to make one`. + +## 向 map 中插入元素 + +插入元素给 map 的语法与数组相似。下面的代码插入一些新的元素给 `map personSalary`。 +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := make(map[string]int) + personSalary["steve"] = 12000 + personSalary["jamie"] = 15000 + personSalary["mike"] = 9000 + fmt.Println("personSalary map contents:", personSalary) +} +``` + +上面的程序输出:`personSalary map contents: map[steve:12000 jamie:15000 mike:9000]`。 + +也可以在声明时初始化一个数组: + +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := map[string]int { + "steve": 12000, + "jamie": 15000, + } + personSalary["mike"] = 9000 + fmt.Println("personSalary map contents:", personSalary) +} +``` + +上面的程序在声明 personSalary 的同时向其中插入了两个元素。接着插入了一个以 "mike" 为键的元素。程序的输出为: + +```golang +personSalary map contents: map[steve:12000 jamie:15000 mike:9000] +``` + +`string` 并不是可以作为键的唯一类型,其他所有可以比较的类型,比如,布尔类型,整型,浮点型,复数类型都可以作为键。如果你想了解更多关于可比较类型的话,请参阅:http://golang.org/ref/spec#Comparison_operators + +## 访问 map 中的元素 + +现在我们已经添加了一些元素给 map,现在让我们学习如何从 map 中提取它们。根据键获取值的语法为:`map[key]`,例如: + +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := map[string]int{ + "steve": 12000, + "jamie": 15000, + } + personSalary["mike"] = 9000 + employee := "jamie" + fmt.Println("Salary of", employee, "is", personSalary[employee]) +} +``` + +上面的程序非常简单。员工 `jamie` 的工资被取出并打印。程序的输出为:`Salary of jamie is 15000`。 + +如果一个键不存在会发生什么?`map` 会返回值类型的 `0 `值。比如如果访问了 `personSalary` 中的不存在的键,那么将返回 `int` 的 0 值,也就是 0。 + +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := map[string]int{ + "steve": 12000, + "jamie": 15000, + } + personSalary["mike"] = 9000 + employee := "jamie" + fmt.Println("Salary of", employee, "is", personSalary[employee]) + fmt.Println("Salary of joe is", personSalary["joe"]) +} +``` + +上面的程序输出为: + +```golang +Salary of jamie is 15000 +Salary of joe is 0 +``` + +上面的程序返回 `joe` 的工资为` 0`。我们没有得到任何运行时错误说明键 joe 在 `personSalary` 中不存在。 + +我们如何检测一个键是否存在于一个 map 中呢?可以使用下面的语法: + +```golang +value, ok := map[key] +``` + +上面的语法可以检测一个特定的键是否存在于 map 中。如果 `ok` 是 `true`,则键存在,value 被赋值为对应的值。如果 `ok` 为 `false`,则表示键不存在。 + +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := map[string]int{ + "steve": 12000, + "jamie": 15000, + } + personSalary["mike"] = 9000 + newEmp := "joe" + value, ok := personSalary[newEmp] + if ok == true { + fmt.Println("Salary of", newEmp, "is", value) + } else { + fmt.Println(newEmp,"not found") + } + +} +``` + +在上面的程序中,第 15 行,`ok` 应该为 `false` ,因为 `joe` 不存在。因此程序的输出为: + +```golang +joe not found +``` + +range for 可用于遍历 map 中所有的元素(译者注:这里 range 操作符会返回 map 的键和值)。 + +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := map[string]int{ + "steve": 12000, + "jamie": 15000, + } + personSalary["mike"] = 9000 + fmt.Println("All items of a map") + for key, value := range personSalary { + fmt.Printf("personSalary[%s] = %d\n", key, value) + } +} +``` + +上面的程序输出如下: + +```golang +All items of a map +personSalary[mike] = 9000 +personSalary[steve] = 12000 +personSalary[jamie] = 15000 +``` + +值得注意的是,因为 map 是无序的,因此对于程序的每次执行,不能保证使用 range for 遍历 map 的顺序总是一致的。 + +## 删除元素 + +`delete(map, key) `用于删除 map 中的 key。delete 函数没有返回值。 + +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := map[string]int{ + "steve": 12000, + "jamie": 15000, + } + personSalary["mike"] = 9000 + fmt.Println("map before deletion", personSalary) + delete(personSalary, "steve") + fmt.Println("map after deletion", personSalary) + +} +``` + +上面的程序删除以 `steve` 为键的元素。程序输出为: + +```golang +map before deletion map[steve:12000 jamie:15000 mike:9000] +map after deletion map[mike:9000 jamie:15000] +``` + +## map 的大小 + +用内置函数 `len` 获取 map 的大小: + +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := map[string]int{ + "steve": 12000, + "jamie": 15000, + } + personSalary["mike"] = 9000 + fmt.Println("length is", len(personSalary)) + +} +``` + +上面程序中,`len(personSalary) `获取 `personSalary` 的大小。上面的程序输出:`length is 3`。 + +## map 是引用类型 + +与切片一样,map 是引用类型。当一个 map 赋值给一个新的变量,它们都指向同一个内部数据结构。因此改变其中一个也会反映到另一个: + +```golang +package main + +import ( + "fmt" +) + +func main() { + personSalary := map[string]int{ + "steve": 12000, + "jamie": 15000, + } + personSalary["mike"] = 9000 + fmt.Println("Original person salary", personSalary) + newPersonSalary := personSalary + newPersonSalary["mike"] = 18000 + fmt.Println("Person salary changed", personSalary) +} +``` + +上面的程序中,第 14 行,`personSalary` 赋值给 `newPersonSalary`。下一行,将 `newPersonSalary` 中 `mike` 的工资改为 `18000`。那么在 `personSalary` 中 `mike` 的工资也将变为 `18000`。程序的输出如下: + +```golang +Original person salary map[steve:12000 jamie:15000 mike:9000] +Person salary changed map[jamie:15000 mike:18000 steve:12000] +``` + +将 map 作为参数传递给函数也是一样的。在函数中对 map 的任何修改都会影响在调用函数中看到。 + +## 比较 map + +map 不能通过 `== `操作符比较是否相等。`== `操作符只能用来检测 map 是否为 nil。 + +```golang +package main + +func main() { + map1 := map[string]int{ + "one": 1, + "two": 2, + } + + map2 := map1 + + if map1 == map2 { + } +} +``` + +上面的程序将会报错:`invalid operation: map1 == map2 (map can only be compared to nil)`。 + +比较两个 map 是否相等的方式是一一比较它们的元素是否相等。我会鼓励你为此编写一个程序,使其工作:) + +我(原文作者)已经将我们讨论的所有概念汇总到一个程序中,你可以从 [github](https://github.com/golangbot/arraysandslices) 下载。 + +## 知识扩展 + +[Go编程基础视频教程笔记](https://study.163.com/course/courseLearn.htm?courseId=306002#/learn/video?lessonId=421019&courseId=306002) + +```golang +package main + +import ( + "fmt" + "sort" +) + +func main(){ + // 方式一 + var m map[int]string // 声明一个map + fmt.Println(m) + m = map[int]string{} // 初始化一个map + fmt.Println(m) + + // 方式二 + var m2 map[int]string = map[int]string{} + fmt.Println(m2) + + // 方式三 + m3 := map[int]string{} + fmt.Println(m3) + + // 设置、获取、删除 + m3[1] = "Tinywan" + a := m3[1] + fmt.Println(m3) // map[1:Tinywan] + fmt.Println(a) // Tinywan + + delete(m3,1) // 删除一个map + fmt.Println(m3) // map[] + + // 复杂map 的操作 + var m5 map[int]map[int]string // 定义 + m5 = make(map[int]map[int]string) // 通过 make 初始化 最外层的 map + + m5[1] = make(map[int]string) // 针对外层value 的map进行初始化 + m5[1][1] = "OK" + m_a := m5[1][1] // 取出map 的值赋予一个变量 + fmt.Println(m_a) // OK + + // 判断一个map 有没有被初始化,使用多返回值判断 + m_b, ok := m5[2][1] + // 判断是否被初始化操作 + if !ok { + m5[2] = make(map[int]string) + } + m5[2][1] = "OK b" + m_b,ok = m5[2][1] + fmt.Println(m_b, ok) // OK b true + + // 迭代操作 + s_map := make([]map[int]string,5) // 以 map 为元素的slice 使用 make 创建一个切片,元素的slic + for _,v := range s_map { + v = make(map[int]string) // v 是值的拷贝 + v[1] = "OK" + fmt.Println(v); + } + fmt.Println(s_map) + + // 针对一个 map 直接操作 + for i := range s_map { + s_map[i] = make(map[int]string) + s_map[i][1] = "OK" + fmt.Println(s_map[i]); + } + fmt.Println(s_map) + + // map 的间接排序 + // map 集合 + map01 := map[int]string{1:"a", 2:"b", 3:"n", 4:"c", 5:"p", 6:"f"} + // 切片 + slice01 := make([]int, len(map01)) + i := 0 + for k, _ := range map01 { + slice01[i] = k + i++ + } + + fmt.Println(slice01) // 返回的是一个无序的数组:[5 6 1 2 3 4] [3 4 5 6 1 2] + sort.Ints(slice01) + fmt.Println(slice01) // 有序的数组:[1 2 3 4 5 6] +} +``` + +希望你喜欢阅读。请留下宝贵的意见和反馈:) \ No newline at end of file diff --git a/images/pointer-explained.png b/images/pointer-explained.png new file mode 100644 index 0000000000000000000000000000000000000000..0954b6351aefab182db62db09020c94b34ce79d1 GIT binary patch literal 17563 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 Vzu|ie91ez%5RnzG5d7-*{{Uh{)zJU| literal 0 HcmV?d00001