package container
import "fmt"
/**
切片
切片本身没有值, 是对底层array的一个view(视图)
所有的切片都是在原arr数组的范围中进行切出数据的!
但是只能向后扩展,不能像前扩展!
切片里面,声明的 var a []int 没有赋值上默认值, 默认是 nil,但是为nil的情况下,也可以直接往里面添加元素!
*/
/**
切片是引用传递, 会直接修改原有的值
*/
// 修改其中的某个值
func updateSlice(s []int){
s[0] = 100
}
func main() {
arr := [...]int{0,1,2,3,4,5,6,7,8,9}
// arr[2:6] = [2 3 4 5]
fmt.Println("arr[2:6] = ", arr[2:6])
// arr[:6] = [0 1 2 3 4 5]
fmt.Println("arr[:6] = ", arr[:6])
// arr[2:] = [2 3 4 5 6 7 8 9]
fmt.Println("arr[2:] = ", arr[2:])
// arr[:] = [0 1 2 3 4 5 6 7 8 9]
fmt.Println("arr[:] = ", arr[:])
/**
通过 s1 := arr[2:6] 声明的切片 这个例子的结论:
(1)s1 := arr[2:6] 想当于就是在原有的 arr 数组基础上,进行的一个部分内存地址的引用的指向,然后声明出的 s1 的这个变量!
修改了 s1 里面的值,也会对原有的 arr 数组产生修改,因为他们使用的都是相同内存地址!
(2)数组里面的每一个值在内存里面都会有一个唯一的内存地址标记!
*/
// 自动类型,获取一个数组的部分值,转换为切片
s1 := arr[2:6]
updateSlice(s1)
// s1 = [100 1 2 3 4 5 6 7 8 9]
fmt.Println("s1 = ", s1)
fmt.Println("arr = ", arr)
/**
此时 s1 里面并没有 6~8 之间的下坐标数, 所以按照常理来说是没有值的!
但是此时却是有值: s2 = [8 9],
为什么会有值?
推论:
(1)这 s2 = [8 9] 的值是原arr数组的值。
(2)这 s2 = [8 9] 的值,是我Go语言获取到 s1 的最后一个值之后,针对最后一个值进行的加1操作!
也就是说 s1 切片里面最后一个值是 5,那么我Go语言获取到这个 5 之后,在这个值上面往后加1,然后5的后面是6!
(1)正确
(2)错误
这两个论证点哪一个是真?
但是继续测试 s2 = [8 9] // 报错 , 结果报错了,说切片超出范围!
由此得知:我 s2 还是针对原arr数组获取的值!也就是说我的切片,切出的值都是基于原arr数组的范围!
所以第一个论证点是正确的!
所有的切片都是在原arr数组的范围中进行切出数据的!
如果说 s1 := arr[2:6] 是这个范围,那么 s2 在s1上切片,s2 := s1[1:3] 是要出错的!因为s2受限于s1,
但是 s2 := arr[6:8] 是受限于 原arr数组!
也就是说 只能向后扩展,不能向前扩展!
*/
s2 := s1[6:8]
// s2 = [8 9] // 报错
fmt.Println("s2 = ", s2)
// s1=[100 3 4 5],len(s1)=4, cap(s1)=8
/**
cap 表示总共有多少个可看的容量, 相当于就是从起始位置算起,只能看后面的,不能看前面的!
也就是说 s1 是从下坐标2开始的,就只能从2开始算起,有多少个可以看的元素!
*/
fmt.Printf("s1=%v,len(s1)=%d, cap(s1)=%d\n",s1,len(s1),cap(s1))
/**
切片添加元素的时候,是基于原arr元素的,
如果超出了原arr数组的长度,Go语言会复制一份,在重新创建一个新的数组,新的数组的长度会比原arr数组要大,
但是新数组的元素如果是旧数组的,那么就会继续使用原数组的元素的内存地址
如果没有超出原arr数组,就把最后面的值给替换掉,那么对原arr数组本身存在数据会产生影响也会进行修改,因为内存地址相同
*/
s3 := arr[4:9]
fmt.Println("s3 = ", s3)
// 往slice切片里面添加一个 元素
s4 := append(s3, 23)
fmt.Println("s4 = ", s4)
fmt.Println("arr = ", arr)
// make 分配函数
/**
make() 只用于映射、切片和程道,不返回指针。要明确的得到指针用 new() 分配
make在分配的时候,不能超过总共大小的元素空间!
比如 make([]int, 5, 10) 在分配的时候,第二个参数的不能大于第三个参数的值!
*/
//创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间
// 相当于就是初始化5个大小的数组切片,然后共10个空间位置
makeA := make([]int, 5, 10) // len(makeA)=5, cap(makeA)=10
fmt.Println("makeA = ", makeA)
// 复制值,把 s1 的值复制到 makeA 中
copy(makeA, s1)
fmt.Println("复制之后的makeA = ", makeA)
// 删除操作
// 复制之后的makeA = [100 3 4 5 0]
// 删除makeA中的第3个元素,下坐标也就是2
makeA = append(makeA[:2], makeA[3:]...)
fmt.Println("删除元素后的 makeA = ", makeA) // [100 3 5 0]
}
网友评论