go 切片
来源:原创
时间:2019-03-05
作者:脚本小站
分类:GoLang
切片的底层是数组 append 当原有容量不够时将会创建一个新的数组,并将原有的值复制到新数组里面。容量小于1000时会以两倍的形式增长,超过1000后以1.25倍的形式增长。
append可以合并多个切片,append(s1, s2 ...)
// 创建两个切片,并分别用两个整数进行初始化 s1 := []int{1, 2} s2 := []int{3, 4} // 将两个切片追加在一起,并显示结果 fmt.Printf("%v\n", append(s1, s2...)) Output: [1 2 3 4]
限制切片长度可以在调用append 时创建一个新的底层数组,防止修改切片时影响到底层数组。
source := []string{"Apple", "Orange", "Plum", "Banana", "Grape"} slice := source[2:3:3] // 限制容量 slice = append(slice, "Kiwi") // 这样就不会修改掉 Banana,而是在一个新的底层数组中操作了
迭代切片:range 创建了每个元素的副本,而不是直接返回对该元素的引用
// 创建一个整型切片 // 其长度和容量都是 4 个元素 slice := []int{10, 20, 30, 40} // 迭代每一个元素,并显示其值 for index, value := range slice { fmt.Printf("Index: %d Value: %d\n", index, value) } Output: Index: 0 Value: 10 Index: 1 Value: 20 Index: 2 Value: 30 Index: 3 Value: 40
查看切片长度容量:
package main import "fmt" func main() { a := []int{1, 2, 3, 4, 5} s := a[1:3:5] //[开始位置 : 结束位置 : 切片容量] fmt.Println("s = ", s) //s = [2 3] fmt.Println("len(s) = ", len(s)) //长度 len(s) = 2 也就是 3-1 fmt.Println("cap(s) = ", cap(s)) //容量 cap(s) = 4 也就是 5-1 }
切片和数组的区别:
package main import "fmt" func main() { a := [5]int{} // 数组[]里面是固定值 s := []int{} // 切片[]里面为空或... fmt.Println(a) s = append(s, 123) fmt.Println(cap(s), len(s), s) }
切片创建函数 make:
package main import "fmt" func main() { s2 := make([]int, 5, 10) // make(切片类型,长度,容量) fmt.Println(s2, len(s2), cap(s2)) //[0 0 0 0 0] 5 10 s3 := make([]int, 5) //默认容量和长度一样 fmt.Println(s3, len(s3), cap(s3)) //[0 0 0 0 0] 5 5 }
截取切片:
package main import "fmt" func main() { array := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} s1 := array[:] // 截取全部 [1 2 3 4 5 6 7 8 9] fmt.Println(s1) s2 := array[2] // 引用元素 3 fmt.Println(s2) s3 := array[1:2:3] // 截取部分 [2] fmt.Println(s3) s4 := array[:6] // 从零开始截取6个 [1 2 3 4 5 6] fmt.Println(s4) s5 := array[3:] // 从第三个开始截取到最后 [4 5 6 7 8 9] fmt.Println(s5) s6 := array[2:5] // 从array[2]开始截取5-2个元素 [3 4 5] fmt.Println(s6) s6[1] = 666 // 改变新切片的值,原切片的值也会被改变 fmt.Println(s6) // [3 666 5] fmt.Println(array) // [1 2 3 666 5 6 7 8 9] }
追加元素 append:
package main import "fmt" func main() { s1 := []int{} fmt.Println(s1) // [] s1 = append(s1, 1) fmt.Println(s1, cap(s1)) // [1] 1 s1 = append(s1, 2) fmt.Println(s1, cap(s1)) // [1 2] 2 s1 = append(s1, 3) fmt.Println(s1, cap(s1)) // [1 2 3] 4 如果超过原来的容量则以两倍的方式进行扩容 }
切片的拷贝 copy:
package main import "fmt" func main() { src := []int{8, 9} dst := []int{1, 2, 3, 4, 5, 6} copy(dst, src) fmt.Println(dst) // [8 9 3 4 5 6] 覆盖原来的元素 }
切片做函数参数:
切片作为函数参数只是复制切片,并没有复制切片指向的底层数组。64 位架构的机器上,一个切片需要 24 字节的内存:指针字段需要 8 字节,长度和容量字段分别需要 8 字节。切片作为函数参数只是复制了24字节。
package main import ( "fmt" "math/rand" "time" ) func InitData(s []int) { rand.Seed(time.Now().UnixNano()) for i := 0; i < len(s); i++ { s[i] = rand.Intn(100) } } func main() { n := 10 s := make([]int, n) InitData(s) fmt.Println(s) }
小练习:猜四位数
package main import ( "fmt" "math/rand" "time" ) /** * 创建随机数 * @param p *int 用来存放随机数的指针 */ func CreateNum(p *int) { rand.Seed(time.Now().UnixNano()) var num int for { num = rand.Intn(10000) if num > 1000 { break } } *p = num } /** * 将创建的随机数放入切片以备后面使用 * @param s []int 用来存放随机数的切片 * @param num int 一个4位随机数 */ func PutSlice(s []int, num int) { s[0] = num / 1000 s[1] = num % 1000 / 100 s[2] = num % 100 / 10 s[3] = num % 10 } /** * 获取用户输入的4位数 * @param s []int 存放4位数的切片 */ func GetInputNumber(s []int) { var num int for { fmt.Println("请输入一个4位数:") fmt.Scan(&num) if num < 10000 && num > 999 { break } fmt.Println("输入错误!") } PutSlice(s, num) } func main() { var randNum int CreateNum(&randNum) randNumber := make([]int, 4) // 产生一个随机数放入切片 PutSlice(randNumber, randNum) inputNumber := make([]int, 4) for { // 获取随机数放入切片 GetInputNumber(inputNumber) // 比较四位数 n := 0 for i := 0; i < 4; i++ { if randNumber[i] > inputNumber[i] { fmt.Printf("第 %d 位小了\n", i+1) } else if randNumber[i] < inputNumber[i] { fmt.Printf("第 %d 位大了\n", i+1) } else { fmt.Printf("第 %d 位猜对了\n", i+1) n++ } } if n == 4 { fmt.Println("全猜对了") break } } }