package main
import (
"fmt"
)
func main() {
fmt.Println("---------------切片")
/*
数组是有固定长度的数据类型,切片和数组类似,有一些共有的属性,但是长度是可变的。
*/
var arr1 [5]int = [5]int{1,2,3,4,5} // 定义并初始化一个数组
var sli1 []int = arr1[1:4] // 由数组得到切片,arr[起始索引:终止索引(但不包括终止索引)]
var sli2 []int = arr1[1:]
var sli3 []int = arr1[2:]
var sli4 []int = arr1[:]
fmt.Println("arr1:", arr1,"\t sli1:", sli1)
fmt.Println("len(sli1):", len(sli1),"\t cap(sli1):", cap(sli1))
// 切片有容量和长度两个属性,长度:当前元素的个数 容量:当前最多可容纳元素的个数, 因此长度不能超过容量
fmt.Printf("%T %T\n", arr1, sli1)
/*
arr1: [1 2 3 4 5] sli1: [2 3 4]
len(sli1): 3 cap(sli1): 4
[5]int []int
*/
fmt.Println("sli2:", sli2)
fmt.Println("sli3:", sli3)
fmt.Println("sli4:", sli4)
/*
sli2: [2 3 4 5]
sli3: [3 4 5]
sli4: [1 2 3 4 5]
*/
var sli5 []int
fmt.Println("sli5:", sli5)
fmt.Printf("sli5:%p\n", &sli5)
fmt.Println("len(sli5):", len(sli5),"\t cap(sli5):", cap(sli5))
// sli5[0] = 10 // 此处直接使用会报错
/*
没有用数组初始化的切片长度和容量都是0
sli5:0xc0000960d8
len(sli5): 0 cap(sli5): 0
*/
sli5 = make([]int, 10, 10)
fmt.Println("sli5:", sli5)
fmt.Printf("sli5:%p\n", &sli5)
fmt.Println("len(sli5):", len(sli5),"\t cap(sli5):", cap(sli5))
sli5[0] = 100
fmt.Println("sli5:", sli5)
/*
sli5: [0 0 0 0 0 0 0 0 0 0]
sli5:0xc0000960d8
len(sli5): 10 cap(sli5): 10
sli5: [100 0 0 0 0 0 0 0 0 0]
*/
/*
内存布局:
1.如果切片使用数组初始化,那么切片的首地址就是起始索引代表元素的地址,
切片的长度 = 起始索引到结束索引-1
切片的容量 = 起始索引到数组结尾
是固定的。
2.如果使用make初始化的切片,那么这个切片的内存控制是由make函数本身实现的,是可变的
*/
sli1[1] = 200
fmt.Println("sli1:", sli1)
fmt.Println("arr1:", arr1)
/*
切片是引用类型,因此用数组初始化切片后,彼此的修改是相互影响的
sli1: [2 200 4]
arr1: [1 2 200 4 5]
*/
// 使用append()给切片增加元素,append会创建一块新增内存来存最后的结果,因此不会修改原来切片对应内存的值
sli1 = append(sli1, 100, 200, 300, 400)
fmt.Printf("sli1:%v %p:\n", sli1, &sli1)
fmt.Printf("arr1[1]:%v %p:\n", arr1[1], &arr1[1])
sli1 = append(sli1, sli1...)
fmt.Printf("sli1:%v %p:\n", sli1, &sli1)
/*
sli1:[2 200 4 100 200 300 400] 0xc000096060:
arr1[1]:2 0xc0000cc068:
sli1:[2 200 4 100 200 300 400 2 200 4 100 200 300 400] 0xc000096060:
*/
var sli6 []int
sli6 = make([]int, 10)
fmt.Println("sli6:", sli6)
fmt.Printf("sli6:%p\n", &sli6)
fmt.Println("len(sli6):", len(sli6),"\t cap(sli6):", cap(sli6))
sli6 = append(sli6, 100, 200, 300, 400)
fmt.Println("sli6:", sli6)
fmt.Printf("sli6:%p\n", &sli6)
fmt.Println("len(sli6):", len(sli6),"\t cap(sli6):", cap(sli6))
/*
sli6: [0 0 0 0 0 0 0 0 0 0]
sli6:0xc000004198
len(sli6): 10 cap(sli6): 10
sli6: [0 0 0 0 0 0 0 0 0 0 100 200 300 400]
sli6:0xc000004198
len(sli6): 14 cap(sli6): 20
*/
/*
字符串和切片:
字符串本身不可修改,如要修改可以先转化成[]byte 或者 []rune,然后对切片进行修改,最后再转化成字符串
*/
str1 := "hello world"
str2 := "你好世界"
fmt.Println("str1:", str1, "\tstr2:", str2)
sli_str1 := []byte(str1)
sli_str2 := []rune(str2)
fmt.Println("sli_str1:", sli_str1, "\tsli_str2:",sli_str2)
sli_str1[0] = 'H'
sli_str2[0] = '霓'
str1 = string(sli_str1)
str2 = string(sli_str2)
fmt.Println("str1:", str1, "\tstr2:", str2)
/*
str1: hello world str2: 你好世界
sli_str1: [104 101 108 108 111 32 119 111 114 108 100] sli_str2: [20320 22909 19990 30028]
str1: Hello world str2: 霓好世界
*/
}