切片的底层是数组 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
}
}
}