数组和切片的区别
数组是需要指定个数的,而切片则不需要。
var SliceName []type
定义一个切片,且切片成员为字符串类型
var names []string
声明切片的同时,为切片分配一个内存地址。
说明:len表示数组长度,即切片的初始长度
var slice1 = make([]type, len)
在函数内,可简写做:
slice1 := make([]type, len)
var names = make([]string,3)
函数内可以写做:
names := make([]string,3)
当然你也可以先声明,然后在初始化
var names []string
names = make([]string,3)
len(SliceName)
package main
import "fmt"
func main() {
names := make([]string,10)
fmt.Printf("切片:%+v\n长度为:%d",names,len(names))
}
结果打印
切片:[ ]
长度为:10
问:明明打印的切片没有成员,为什么长度为10?
答:可以看见我们打印出的结果是[ ]
而不是[]
。这里边有9个空格,即是10个成员间的9个分隔符(空格)。我们看不到成员,是因为这10个成员的值默认都是空(字串不赋值默认为空)。如果我们定义切片成员类型是int
我们将看到打印出10个0
(int类型不赋值,默认为0)
package main
import "fmt"
func main() {
slice1 := make([]int,10)
fmt.Printf("切片:%+v\n长度为:%d",slice1,len(slice1))
}
结果:
切片:[0 0 0 0 0 0 0 0 0 0]
长度为:10
说明:
- len是目前的成员数
- cap是切片的上限
每增加 一个成员,len 值加1,成员数达到cap值后,cap值翻倍。
slice1 := make([]type, len, cap)
names := make([]string,3,5)
cap(SliceName)
package main
import "fmt"
func main() {
names := make([]string,3,5)
fmt.Printf("切片长度为:%d,容量为:%d",len(names),cap(names))
}
结果打印
切片长度为:3,容量为:5
在函数内我们用
:
在赋值的同时也声明了切片(只用=
仅赋值但不能声明切片)
names :=[]string{"刘备","关羽","张飞" }
package main
import "fmt"
func main() {
names := []string{"刘备","关羽","张飞"}
fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}
结果显示
打印切片:[刘备 关羽 张飞]
长度为:3
容量为:3
s := arr[:]
package main
import "fmt"
func main() {
namesArray := [3]string{"刘备","关羽","张飞"} //定义一个数组
names := namesArray[:] //声明切片并用数组给切片赋值
fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}
执行结果为:
打印切片:[刘备 关羽 张飞]
长度为:3
容量为:3
前提:设
N
为起始位置,到第M
个成员。
s := arr[N:M]
- 需求:从元素的位置1(刘备是位置0,关羽是位置1),取到第3个成员(第一个成员是刘备,第二个是关羽,第三个是张飞)
- 预计:切片将取到 关羽、张飞两个成员。
package main
import "fmt"
func main() {
namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} //定义一个数组
names := namesArray[1:3]
fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}
打印切片:[关羽 张飞]
长度为:2
容量为:4
长度是2,因为我们取到了两个成员:关羽、张飞
容量是4,这是从起始位置1(关羽)起,计算到数组结尾(诸葛亮),一共四个位置。
虽然没有取到赵云和诸葛亮,但是容量已经加进来了
s := arr[N:]
package main
import "fmt"
func main() {
namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} //定义一个数组
names := namesArray[1:]
fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}
打印切片:[关羽 张飞 赵云 诸葛亮]
长度为:4
容量为:4
s := arr[:M]
- 需求:从开头(位置0)取到第二个成员(关羽)
package main
import "fmt"
func main() {
namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} //定义一个数组
names := namesArray[:3]
fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names))
}
结果打印
打印切片:[刘备 关羽 张飞]
长度为:3
容量为:5
说明:通过切片s初始化切片s1
s2 := s1[N:M]
方法同数组赋值给切片
package main
import "fmt"
func main() {
var names []string
fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
if names == nil {
fmt.Printf("切片是空的")
}else {
fmt.Println("切片不为空")
}
}
打印切片:[]
长度为:0
容量为:0
切片是空的
package main
import "fmt"
func main() {
var names = make([]string,0,0)
fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
if names == nil {
fmt.Println("切片是空的")
}else {
fmt.Println("切片不为空")
}
}
结果打印
打印切片:[]
长度为:0
容量为:0
切片不为空
func append(slice []Type, elems ...Type) []Type
names = append(names,"赵云")
package main
import "fmt"
func main() {
names := []string{"刘备","关羽","张飞"}
fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
names = append(names,"赵云")
fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
添加成员后:[刘备 关羽 张飞 赵云]
长度为:4
容量为:6
结果可见,当成员达到容量上限后,再添加成员,长度增加一,但是容量会翻倍。
我们再继续添加成员,也想验证一下长度和容量的变化。
package main
import "fmt"
func main() {
names := []string{"刘备","关羽","张飞"}
fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
names = append(names,"赵云")
fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
names = append(names,"马超","黄忠","魏延")
fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
添加成员后:[刘备 关羽 张飞 赵云]
长度为:4
容量为:6
==================
添加成员后:[刘备 关羽 张飞 赵云 马超 黄忠 魏延]
长度为:7
容量为:12
可以看到,成员再次超过容量时,容量在当前容量的基础上翻倍。
package main
import "fmt"
func main() {
names := []string{"刘备","关羽","张飞"}
fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
names2 := append(names,"赵云")
fmt.Printf("==================\n新切片:%+v\n长度为:%d\n容量为:%d\n",names2,len(names2),cap(names2))
fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
新切片:[刘备 关羽 张飞 赵云]
长度为:4
容量为:6
==================
再次打印原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
结果可见,append对于原切片并不会造成影响。
func copy(dst []Type, src []Type) int
返回成功拷贝了多少个元素
package main
import "fmt"
func main() {
names := []string{"刘备","关羽","张飞"}
fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
names2 := make([]string,4,4)
num := copy(names2,names)
fmt.Printf("==================\n新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2))
fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
新切片:[刘备 关羽 张飞 ]
拷贝了3个元素
长度为:4
容量为:4
==================
再次打印原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
如上可见,初始化长度为4,拷贝了3个元素,但是我们可以看到新切片最后有一个空格,是第3和第4个元素的分隔符,只是第四个元素为空
package main
import "fmt"
func main() {
names := []string{"刘备","关羽","张飞"}
fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
names2 := make([]string,2,4)
num := copy(names2,names)
fmt.Printf("==================\n新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2))
fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
新切片:[刘备 关羽]
拷贝了2个元素
长度为:2
容量为:4
==================
再次打印原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
新切片未初始化的结果类似于初始化长度为0的切片
package main
import "fmt"
func main() {
names := []string{"刘备","关羽","张飞"}
fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
var names2 []string
if names2 == nil{
fmt.Println("==================\nnames2 为空")
}else{
fmt.Println("==================\nname2 不为空")
}
num := copy(names2,names)
fmt.Printf("新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2))
fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names))
}
原切片:[刘备 关羽 张飞]
长度为:3
容量为:3
==================
names2 为空
新切片:[]
拷贝了0个元素
长度为:0
容量为:0
==================
再次打印原切片:[刘备 关羽 张飞]
长度为:3
容量为:3