今天周末,分段学习,对学习的第一段内容总结
1. 从数组中切片
切片后仍然是引用
// 结构体也可以用于切片
d := [5]struct{
x int
}{}
s := d[:]
s[0].x = 10
s[1].x = 20
// d 后 s 同时改变
fmt.Println(d, s)
// 输出
// [{10} {20} {0} {0} {0}] [{10} {20} {0} {0} {0}]
2. 切片append返回一个新的切片(非引用)
a := []int{1, 2, 3, 4}
b := append(a, 5)
// 取地址时候必须要用& 不像其它类型/值
// 地址不同 因为也是新的对象
fmt.Printf("a地址:%p;b地址: %p\n", &a, &b)
// a地址:0xc000118018;b地址: 0xc000118030
// ...将切片展开 插入
c := append(a, b...)
fmt.Println(c)
// [1 2 3 4 1 2 3 4 5]
arr := [...]int{2,9,10}
d := append(a, arr[:]...) // 数组需要切了后 append
fmt.Println(d)
// [1 2 3 4 2 9 10]
3. copy复制数组
copy(a,c) 将c拷贝到a
a := []int{1,2,3}
b := []int{4,6,8,12}
copy(a,b) // 拷贝时候根据最短的切片决定 b 拷贝 到 a
fmt.Println(a, b)
// [4 6 8] [4 6 8 12]
4. 切片后容量cap由原切片的剩余元素决定
a := []int{0,1,2,3,4,5,6,7,8}
b := a[4:6] // 元素为 [4,5] +剩余元素为 6,7,8 ,所以cap为 2 + 3 = 5
fmt.Println(b, len(b), cap(b))
//[4 5] 2 5
5. 遍历切片
a := []int{2,4,8}
for index, value := range a {
fmt.Printf("index: %d value: %d\n", index, value)
}
// index: 0 value: 2
// index: 1 value: 4
// index: 2 value: 8
6. 切片resize 一个切片长度只有1,如果继续切超过其长度,其实也是可以的
a := []int{0,1,2,3,4,5,6,7,8,9}
b := a[3:4] //切完后为 [3]
c := b[:3] // 此时切已经操作了b元素个数,原b只有1个元素,这个时候切的是 3,4,5 相当于在a的基础上做了切
fmt.Println(b, c)
// [3] [3 4 5]
7. 切片会随着元素增多而动态扩充cap,扩充方式为2倍法
a := make([]int, 1) // 默认等于 make([]int, 1,1)因此 len = cap
c := 1 // 初始化cap
for i := 0; i < 100; i ++ {
a = append(a, i)
if cap(a) != c {
fmt.Printf("cap %d -> %d\n", c, cap(a))
c = cap(a)
}
}
//cap 1 -> 2
//cap 2 -> 4
//cap 4 -> 8
//cap 8 -> 16
//cap 16 -> 32
//cap 32 -> 64
//cap 64 -> 128
8. 字符串 也可以切片
因为:它的底层是一个[]byte数组
str := "hello world"
a := str[6:]
fmt.Printf("类型%T 原生情况:%#v\n", a, a)
// 类型string 原生情况:"world"
9. 字符串改变
默认情况下字符串不可改变
str := "hello world"
// a := str[:]
// 错误写法 切出来后还是string类型 这里不能赋值
// a[0] = 'b'
// 先转[]byte 对于中文转 []rune- unicode后操作,然后转换会string
b := []byte(str)
b[0] = 'H'
str = string(b)
fmt.Println(str)
// Hello world
str1 := "我的祖国"
c := []rune(str1)
c[2] = '家'
c[3] = '乡'
str1 = string(c)
fmt.Println(str1)
// 我的家乡
10. go中单引号和双引号的区别
- 单 - 字符
- 双 -字符串
网友评论