目录
1.5 超出原 slice.cap 限制,就会重新分配底层数组,即便原数组并未填满。
1.6 slice中cap重新分配规律:1->2->4->8->16->32->64->
1.7 copy :函数 copy 在两个 slice 间复制数据,复制长度以 len 小的为准。两个 slice 可指向同一底层数组,允许元素区间重叠。
2.2 make: 它只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。
1、切片
切片Slice · Go语言中文文档 (topgoer.com)
1. 切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。
2. 切片的长度可以改变,因此,切片是一个可变的数组。
3. 切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。
4. cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。
5. 切片的定义:var 变量名 []类型,比如 var str []string var arr []int。
6. 如果 slice == nil,那么 len、cap 结果都等于 0。
1.1 切片初始化
package main
import (
"fmt"
)
func main() {
//1.声明切片
var s1 []int
if s1 == nil {
fmt.Println("是空")
} else {
fmt.Println("不是空")
}
// 2.:=
s2 := []int{}
// 3.make()
var s3 []int = make([]int, 0)
fmt.Println(s1, s2, s3)
// 4.初始化赋值
var s4 []int = make([]int, 0, 0)
fmt.Println(s4)
s5 := []int{1, 2, 3}
fmt.Println(s5)
// 5.从数组切片
arr := [5]int{1, 2, 3, 4, 5}
var s6 []int
// 前包后不包
s6 = arr[1:4]
fmt.Println(s6)
//切片初始化
arr2 := [...]int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
slice5 := arr2[2:8]
slice6 := arr2[0:6] //可以简写为 slice := arr[:end]
slice7 := arr2[5:10] //可以简写为 slice := arr[start:]
slice8 := arr2[0:len(arr)] //slice := arr[:]
slice9 := arr2[:len(arr)-1] //去掉切片的最后一个元素
fmt.Printf("局部变量: arr2 %v\n", arr2)
fmt.Printf("局部变量: slice5 %v\n", slice5)
fmt.Printf("局部变量: slice6 %v\n", slice6)
fmt.Printf("局部变量: slice7 %v\n", slice7)
fmt.Printf("局部变量: slice8 %v\n", slice8)
fmt.Printf("局部变量: slice9 %v\n", slice9)
}
1.2 通过make来创建切片
1.3 切片的内存布局

package main
import (
"fmt"
)
func main() {
//通过make来创建切片,cap是切片的容量,那怎么追加容量?
var slice10 []int = make([]int, 10)
//slice10 := make([]int, 10)
slice11 := make([]int, 10)
slice12 := make([]int, 2, 5)
fmt.Printf("make局部slice3 :%v\n", slice10)
fmt.Printf("make局部slice4 :%v\n", slice11)
fmt.Printf("make局部slice5 :%v len:%d cap:%d\n", slice12, len(slice12), cap(slice12))
s10 := []int{0, 1, 2, 3, 8: 100} // 通过初始化表达式构造,可使用索引号。
fmt.Println(s10, len(s10), cap(s10))
//切片的内存布局
data := [...]int{0, 1, 2, 3, 4, 5}
s := data[1:3]
fmt.Printf("data :%v len:%d cap:%d\n", data, len(data), cap(data))
fmt.Printf("data的切片s :%v len:%d cap:%d\n", s, len(s), cap(s))
//使用 make 动态创建slice,避免了数组必须用常量做长度的麻烦。还可用指针直接访问底层数组,退化成普通数组操作。
a := []int{0, 1, 2, 3}
p := &a[2] // *int, 获取底层数组元素指针。
*p += 100
fmt.Println(a)
//多维
datas := [][]int{
[]int{1, 2, 3},
[]int{100, 200},
[]int{11, 22, 33, 44},
}
fmt.Println(datas)
//可直接修改 struct array/slice 成员。
d := [5]struct {
x int
}{}
b := d[:]
d[1].x = 10
b[2].x = 20
fmt.Println(d)
fmt.Printf("%p, %p\n", &d, &d[0])
fmt.Println(b)
fmt.Printf("%p, %p\n", &b, &b[0])
//输出
// [{0} {10} {20} {0} {0}]
// 0xc00000e480, 0xc00000e480
// [{0} {10} {20} {0} {0}]
// 0xc000008240, 0xc00000e480
}
1.4 用append内置函数操作切片(切片追加)
//append :向 slice 尾部添加数据,返回新的 slice 对象
var a = []int{1, 2, 3}
fmt.Printf("slice a : %v\n", a)
var b = []int{4, 5, 6}
fmt.Printf("slice b : %v\n", b)
c := append(a, b...) //...
fmt.Printf("slice c : %v\n", c)
d := append(c, 7)
fmt.Printf("slice d : %v\n", d)
e := append(d, 8, 9, 10)
fmt.Printf("slice e : %v\n", e)
s11 := make([]int, 0, 5)
fmt.Printf("%p\n", &s11)
s12 := append(s1, 1)
fmt.Printf("%p\n", &s12)
fmt.Println(s11, s12)
1.5 超出原 slice.cap 限制,就会重新分配底层数组,即便原数组并未填满。
package main
import (
"fmt"
)
func main() {
data := [...]int{0, 1, 2, 3, 4, 10: 0}
s := data[:2:3] //cap=max-low=3-0=3
fmt.Println(s, cap(s), &s[0], &data[0])
s = append(s, 100, 200) // 一次 append 两个值,超出 s.cap 限制。
fmt.Println(s, data) // 重新分配底层数组,与原数组无关。
fmt.Println(&s[0], &data[0]) // 比对底层数组起始指针。
//输出
// [0 1] 3 0xc000060060 0xc000060060
// [0 1 100 200] [0 1 2 3 4 0 0 0 0 0 0]
// 0xc00000e3f0 0xc000060060
}
1.6 slice中cap重新分配规律:1->2->4->8->16->32->64->
package main
import (
"fmt"
)
func main() {
s := make([]int, 0, 1)
c := cap(s)
for i := 0; i < 50; i++ {
s = append(s, i)
if n := cap(s); n > c {
fmt.Printf("cap: %d -> %d\n", c, n)
c = n
}
}
}
1.7 copy :函数 copy 在两个 slice 间复制数据,复制长度以 len 小的为准。两个 slice 可指向同一底层数组,允许元素区间重叠。
package main
import (
"fmt"
)
func main() {
data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println("array data : ", data)
s1 := data[8:]
s2 := data[:5]
fmt.Printf("slice s1 : %v\n", s1)
fmt.Printf("slice s2 : %v\n", s2)
copy(s2, s1)
fmt.Printf("copied slice s1 : %v\n", s1)
fmt.Printf("copied slice s2 : %v\n", s2)
fmt.Println("last array data : ", data)
}
array data : [0 1 2 3 4 5 6 7 8 9]
slice s1 : [8 9]
slice s2 : [0 1 2 3 4]
copied slice s1 : [8 9]
copied slice s2 : [8 9 2 3 4]
last array data : [8 9 2 3 4 5 6 7 8 9]
1.8 slice遍历:
package main
import (
"fmt"
)
func main() {
data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
slice := data[:]
for index, value := range slice {
fmt.Printf("inde : %v , value : %v\n", index, value)
}
}
2、指针
var a *int
*a = 100
fmt.Println(*a)
会报错,没有分配内存空间。要分配内存,就引出来今天的new和make。
2.1 new:少用
a := new(int)
b := new(bool)
2.2 make: 它只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。
使用make进行初始化,然后才可以对它们进行操作。
package main
import "fmt"
func main() {
var b map[string]int
b = make(map[string]int, 10)
b["测试"] = 100
b["测"] = 20
fmt.Println(b, len(b))
var num int = 0
ptr := &num
*ptr = 10
fmt.Println(num)
}
3816



被折叠的 条评论
为什么被折叠?



