一.字符串拼接
1.加号连接
2.fmt.Sprintf(format string,a ...interface{})string
3.string.Join(elems []string, sep string)string
4.使用strings.Builder、bytes.Buffer(两者速度相似)或者strings.Buffer(最快)
当有大量的string需要拼接时,用strings.Builder效率最高
分析:
- 字符串在Go语言中是不可变类型,占用内存大小是固定的
- 使用 + 每次都会重新分配内存
- strings.Builder,bytes.Buffer底层都是[]byte数组
- 内存扩容策略,不需要每次拼接重新分配内存
二.byte和rune
1.string中每个元素叫“字符”,字符有两种:
byte:1个字节,代表ASCII码的一个字符
rune:4个字节,代表一个UTF-8字符,一个汉字(占3个byte长度)可用一个rune表示
2.string底层是byte数组
3.string可以转换为[]byte或[]rune类型
4.string是常量,不能修改其中的字符
三.常量(const类型)不能进行强制转换
四.二维数组初始化
第1维可以用...推测,第2维不能用...
例:var arr2 = [...][3]int{{1},{2,3}}
五.切片
1.(里面含指针)
2.二维数组各行的列数相等,但二维切片各行的len可以不等
3.append是在len之后追加的,比如
s := make([]int, 3, 5)
==>[0, 0, 0]
s = append(s, 100)
==>[0, 0, 0, 100]
s := make([]int, 0, 5)
==>[]
s = append(s, 100)
==>[100]
切片相对于数组最大的特点就是可以追加元素,可以自动扩容
4.截取子切片
s := make([]int, 3, 5) //len = 3, cap = 5 sub_slice = s[1:3] //len = 2(1,2), cap = 4(1,2,3,4)
- 刚开始,子切片和母切片共享底层的内存空间,修改子切片会反映到母切片上,在子切片上执行append会把新元素放到母切片预留的内存空间上
- 当子切片不断执行append,消耗完了母切片预留的内存空间,子切片跟母切片就会发生内存分离,此后两个切片没有任何关系
六.map
1.初始化
- m = make(map[string]int) //初始化,容量为0
- m = make(map[string]int, 5) //初始化,容量为5。强烈建议初始化时给一个合适的容量,减少扩容的概率
- m = map[string]int{"语文":0,"数学":39} //初始化时直接赋值
2.添加key:mp[“数学”] = 89
3.删除key:delete(mp, "数学")
4.value, ok := mp["A"] //ok判断map中是否有键值为“A”的键值对
七.管道(通道)
- 底层实现是 环形队列
- range遍历管道时要先close,不然会产生死锁:读到最后一个元素之后会堵塞,因为系统不排除之后还有数据要读入的可能,就会一直等在那儿造成堵塞 。
for循环不用
两者共同点:管道里被遍历到的元素都会被取出,所以当你将管道里所有的元素都遍历一遍之后,管道里也没数据了
八.引用类型
- slice、map和channel是go语言里的3种引用类型,都可以通过make函数来进行初始化(申请分配内存)
- 因为它们都包含一个指向底层数据结构的指针,所以称之为“引用”类型
- 引用类型未初始化时都是nil,可以对它们执行len()函数,返回0