go的Day 04总结 内置函数,递归, 数组与切片,map,包
Day 04
内置函数
-
close:主要用来关闭channel -
len:用来求长度,比如:strings、array、slice、map、channel -
new:用来分配内存,主要用来分配值类型内存。比如:int、struct。返回的是指针。var b *int b = new(int) *b = 100 -
make:用来分配内存,主要是用来分配引用类型内存。比如:map、channel、slice等类型。var c chan int c = make(chan int, 4)make和new的区别:package main import "fmt" func main() { s1 := new([]int) fmt.Println(s1) s2 := make([]int, 10) fmt.Println(s2) *s1 = make([]int, 5) fmt.Println(*s1) } -
append:用来追加元素到数组、slice中。对于slice 即使未初始化,也可以直接使用append方法,而未初始化的切片,不能使用 slice[index]=3这样的赋值var a []int a = append(a, 1) -
panic、recover:用来做错误处理。package main import ( "fmt" "math/rand" "time" ) func testRecover(a int, b int) { defer func() { if err := recover(); err != nil { fmt.Println(err) } }() c := a / b fmt.Printf("%d / %d = %d\n", a, b, c) } func init() { rand.Seed(time.Now().UnixNano()) } func main() { for { testRecover(rand.Intn(1000), rand.Intn(10)) time.Sleep(time.Millisecond * 100) } }
递归函数
自己调用自己的函数就叫做递归。
-
阶乘
package main import "fmt" func calc(n int) int { if n <= 1 { return 1 } return calc(n - 1) * n } func main() { fmt.Println(calc(10)) } -
Fibonacci 数列
package main import "fmt" func fibonacci(n int) int { if n <= 2 { return 1 } return fibonacci(n - 1) + fibonacci(n - 2) } func main() { fmt.Println(fibonacci(3)) } -
递归的设计原则
-
一个大的问题能够分解的同等问题的小问题。
-
定义好终止递归的条件。
-
闭包
闭包: 一个函数和与其相关的引用环境组合而成的实体。
闭包的一个例子:
package main
import (
"fmt"
"strings"
)
func makeSuffixFunc(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}
func main() {
func1 := makeSuffixFunc(".bmp")
func2 := makeSuffixFunc(".jpg")
fmt.Println(func1("hello"))
fmt.Println(func2("name"))
}
数组与切片
-
数组:是同一种数据类型的固定长度序列。
-
数组定义:
var a [len]int,比如:var a [5]int,数组长度一旦定义是不可变的。 -
长度是数组类型的一部分,因此:
var a[5] int和var a [10]int是不同的类型。 -
数组可以通过下标进行访问,下标是从0开始,最后一个元素的下标是:
len - 1for i := 0; i < len(a); i++ { fmt.Println(a[i]) }for _, item := range a { fmt.Println(item) } -
访问越界,如果下标在数组合法范围之外,则触发访问越界。会 panic
-
数组是值类型,因此改变副本的值并不会改变本身的值。
-
数组初始化
var a [5]int = [5]int{1,2,3,4,5}// 当初始化使用的数值不够的情况下,其余为 0 var a [5]int = [5]int{1,2,3,4}var a = [5]int{1,2,3,4,5}var a = [...]int{1,2,3,4,5}var a = [5]string{3:"hello world", 4: "tom"} -
多维数组
var a [4][2]intvar a [4][2]int = [4][2]int{{0, 1}, {0, -1}, {1, 0}, {-1,0}}var a = [4][2]int{{0, 1}, {0, -1}, {1, 0}, {-1,0}}var a [4][2]int = [...][2]int{{0, 1}, {0, -1}, {1, 0}, {-1,0}}var a = [...][...]int{{0, 1}, {0, -1}, {1, 0}, {-1,0}} -
多维数组遍历
package main import "fmt" func main() { var a [4][2]int = [...][2]int{{0, 1}, {0, -1}, {1, 0}, {-1,0}} for row, arr := range a { for col, val := range arr { fmt.Println(row, col, val) } } }
切片
-
切片:切片是数组的一个引用,因此切片是引用类型。
-
切片的长度可以改变,因此,切片是一个可变数组。
-
切片的遍历方式和数组一样。同样可以使用
len()计算长度。 -
cap可以计算slice的最大容量。0 <= len(slice) <= cap(slice),其中array是slice引用的数组。 -
切片的定义:
var 变量名 []类型,比如:var str []stringvar a = [5]int{1,2,3,4,5} var sliceA = a[2:4] fmt.Println(a) fmt.Println(sliceA)// 直接包含整个数组 var sliceA = a[:]// 只说明结束为止,开始位置默认为0 var sliceA = a[:3]// 只说明开始位置,结束位置默认为最后 var sliceA = a[2:] -
切片的内存布局
-
通过
make来创建切片var slice []int = make([]int, 10)var slice []int = make([]int, 10, 100) -
用
append内置函数操作切片slice = append(slice, 10)// 合并两个切片 var a []int = []int{1,2,3} var b []int = []int{4,5,6} var c = append(a, b...) -
for range遍历切片 -
切片
resize -
切片的拷贝
copy函数:copy(dst, src []Type) -
string与slicestring底层就是一个byte数组。因此,可以可以进行切片操作。 -
string的底层布局 -
string根据unicode进行拆分:rune函数。s1 := []rune(s) -
排序和查找操作
排序操作主要都在
sort包中,导入就可以使用了。import "sort"sort.Ints()对整数进行排序。sort.Strings()对字符串进行排序。sort.Float64s()对浮点数进行排序。sort.SearchInts(a []int, x int)从数组a中查找x,其中a必须是有序的。sort.SearchStrings(a []string, x string)从数组a中查找x,其中a必须是有序的。sort.SearchFloat64s(a []float64, x float64)从数组a中查找x,其中a必须是有序的。
map 数据结构
-
map 简介
key-value 的数据结构,又叫字典或关联数组。
-
声明
var map1 map[string]int var map1 map[string]string var map1 map[int]string var map1 map[string]map[string]int声明是不会分配内存的,需要使用
make进行初始化。var map1 map[string]int map1 = make(map[string]int) map1 = make(map[string]int, 10) // 第二个参数数字是 map 的容量也可以在声明的时候直接初始化。
var map1 map[string]int = map[string]int{ "hello": 1, }map中后面的值类型也可以是一个mappackage main import "fmt" func main() { map1 := make(map[string]map[string]string) map1["key1"] = make(map[string]string) map1["key1"]["key2"] = "hello" map1["key1"]["key3"] = "world" fmt.Println(map1) }
-
-
map相关操作 -
map是引用类型 -
slice of map
-
map排序- 先获取所有的 key,把 key 进行排序
- 按照排好序的 key 进行遍历
- map 中的 key 是无序的
-
map 反转
- 初始化另外一个 map,把 key、value 互换即可。
包
-
golang中的包
- golang目前有150个标准的包,覆盖了几乎所有的基础库
- golang.org有所有包的文档
-
线程同步
import ("sync")- 互斥锁
var mu sync.Mutex - 读写锁
var mu sync.RWMutex
-
go get 安装第三方包
go get github.com/go-sql-driver/mysql

浙公网安备 33010602011771号