Go学习笔记-Go语言数组array和切片slice

##Go 语言中定义数组主要包括以下四种形式:
var <数组名称> [<数组长度>]<元素类型>
var <数组名称> = [<数组长度>]<元素类型>{元素1, 元素2, …}
var <名称> [<长度>]<元素类型> = […]<元素类型>{元素1, 元素2, …}
var <名称> [<长度>]<元素类型> = […]<元素类型>{索引1: 元素1, 索引2: 元素2, …}
在数组定义完成之后,可以通过索引来操作数组中的元素:
<数组名称>[<索引>] = <变量>
<变量> = <数组名称>[<索引>]
*****
func main() {
var a [2]int = [2]int{1}
b := [2]int{1}
var c [2]int = [...]int{1, 2}
d := [...]int{1, 2, 3, 4}
var e [5]int = [...]int{2: 2, 4: 5}
f := [...]int{2: 2, 4: 5}
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(d)
fmt.Println(e)
fmt.Println(f)
d[1] = 11
fmt.Println(d)
}
##数组的比较
在 Go 语言中比较两个数组具有以下要求和限制:
比较的数组必须具有相同的类型(即相同的长度和元素类型)
数组之间可以使用 == 或 != 号进行比较
数组之间不可以使用 >、>=、< 或 <= 进行比较

*****
func main() {
a := [1]int{1}
b := [1]int{1}
c := [1]int{2}
// d := [2]int{1}
fmt.Println(a == b)
fmt.Println(a == c)
}
##多维数组
Go 语言中允许使用多维数组,其包含以下特性:
多维数组可以拥有 n 个维度,n >= 1
由于数组属于值类型,多维数组的所有维度都会在创建时自动初始化零值
多维数组的比较遵循一维数组之间比较的所有规则
*****
func main() {
a := [2]int{1, 1}
fmt.Println(a)
b := [1][1]int{[1]int{1}}
fmt.Println(b)
c := [2][2]int{
[2]int{1, 2},
[2]int{3, 4},
}
fmt.Println(c)
d := [2][2]int{
1: [2]int{1, 2},
0: [2]int{3, 4},
}
fmt.Println(d)
e := [2][2][2]int{
0: [2][2]int{
1: [2]int{1, 2},
0: [2]int{3, 4},
},
1: [2][2]int{
[2]int{5, 6},
[2]int{7, 8},
},
}
fmt.Println(e)
}
##数组与指针
Go 语言中的数组与指针主要包括以下关系:
指向数组的指针
元素类型为指针的数组
使用 new 关键字所创建的就是指向数组
*****
func main() {
a := new([3]int)
fmt.Println(a)
b := [3]*int{}
fmt.Println(b)
tmp := 1
b[0] = &tmp
fmt.Println(b)
c := *b[0]
fmt.Println(c)
}
###Go语言切片 slice
##数组与切片的区别
Go 语言中数组与切片主要有以下区别:
切片本身不是数组,但底层指向数组
切片本身不可以直接进行比较,而数组可以
切片是变长数组的替代方案,可以关联底层数组的局部和全部
切片是引用传递(传递指针地址),而数组是值传递(元素值发生拷贝)
切片可以直接创建、引用其它切片或数组创建
如果多个切片指向相同的底层数组,其中一个的值修改会影响所有其它切片
##创建和使用切片
在 Go 语言中可以通过和创建数组类似的方法创建切片:
var <切片名称> []<元素类型>
var <切片名称> = []<元素类型>{元素1, 元素2, …}
var <切片名称> []<元素类型> = []<元素类型>{索引1: 元素1, 索引2: 元素2, …}
当然,也可以通过 make() 方法直接创建切片:
make() 方法的签名为:make([]T, length, capacity)
其中,length 表示需要创建切片的初始长度(即元素个数)
capacity 表示创建切片的初始容量(可扩容),可省略
当 capacity 被省略时,默认和 length  相同
##在切片创建完成之后,可以通过索引来操作切片中的元素:
<切片名称>[<索引>] = <变量>
<变量> = <切片名称>[<索引>]
或者,可以相应的方法来得知切片状况:
使用 len() 方法来获取元素个数:len(s)
使用 cap() 方法来获取切片容量:cap(s)
*****
func main() {
var s []int
fmt.Println(s == nil) //true
var s1 = []int{1, 2, 3, 4, 5}
fmt.Println(s1)
var s2 []int = []int{5: 1, 1: 2, 0: 3}
fmt.Println(s2) //[3 2 0 0 0 1]
s = []int{1, 2, 3}
fmt.Println(s)
a := s[0]
fmt.Println(a)
s[1] = 4
fmt.Println(s)
//make() len(s) cap(s)
ss := make([]int, 0)
fmt.Println(ss == nil) //false
fmt.Println(len(ss), cap(ss))
sss := make([]int, 3, 5)
fmt.Println(len(sss), cap(sss))
fmt.Println(sss)
}
##切片的 reslice 操作
Go 语言中已经创建的切片还可以进行二次切片操作,称为 reslice:
reslice 的基本格式为:s2 := s1[index1:index2:capacity]
reslice 时的索引以源切片为准
新切片和源切片共享同一个底层数组
索引不可以超过源切片的容量(cap(s))
索引越界不会导致底层数组的重新分配而是引发运行时错误
新切片在未重新分配底层数组之前,所有操作都会和源切片同步,反之亦然
*****
func main() {
s := []int{1, 2, 3, 4, 5}
fmt.Println(len(s), cap(s), s) //5 5 [1 2 3 4 5]
ss := s[0:3]
fmt.Println(len(ss), cap(ss), ss)    //3 5 [1 2 3]
sss := s[2:]                         //s[2:5]
fmt.Println(len(sss), cap(sss), sss) //3 3 [3 4 5]
ssss := s[2:4]
fmt.Println(len(ssss), cap(ssss), ssss) //2 3 [3 4]
ssss[0] = 9
fmt.Println(s)    //[1 2 9 4 5]
fmt.Println(ss)   //[1 2 9]
fmt.Println(sss)  //[9 4 5]
fmt.Println(ssss) //[9 4]
}
##向切片追加元素
Go 语言中可以通过 append() 方法对切片追加元素:
append() 方法的签名为:append(slice, elements...)
可以直接在切片尾部追加元素
也可以将一个切片追加到另一个切片尾部
如果新切片的长度未超过源切片的容量,则返回源切片
如果追加后的新切片长度超过源切片的容量,则会返回全新的切片
*****
func main() {
s := []int{1, 2, 3, 4, 5}
fmt.Printf("s: %p %d %d %v\n", s, len(s), cap(s), s) //s: 0xc04200bfb0 5 5 [1 2 3 4 5]
fmt.Printf("s: %p %d %d %[1]v\n", s, len(s), cap(s)) //s: 0xc04200bfb0 5 5 [1 2 3 4 5]
ss := append(s, 6)
fmt.Printf("ss: %p %d %d %[1]v\n", ss, len(ss), cap(ss)) //ss: 0xc042004320 6 10 [1 2 3 4 5 6]
ss[0] = 9
fmt.Printf("s: %p %d %d %[1]v\n", s, len(s), cap(s))     //s: 0xc04200bfb0 5 5 [1 2 3 4 5]
fmt.Printf("ss: %p %d %d %[1]v\n", ss, len(ss), cap(ss)) //ss: 0xc04205e050 6 10 [9 2 3 4 5 6]
//*****
s1 := make([]int, 3, 5)
fmt.Printf("s1: %p %d %d %[1]v\n", s1, len(s1), cap(s1)) //s1: 0xc042031da0 3 5 [0 0 0]
ss1 := append(s1, 1)
fmt.Printf("ss1: %p %d %d %[1]v\n", ss1, len(ss1), cap(ss1)) //ss1: 0xc042031da0 4 5 [0 0 0 1]
ss1[0] = 7
fmt.Printf("s1: %p %d %d %[1]v\n", s1, len(s1), cap(s1))     //s1: 0xc042031da0 3 5 [7 0 0]
fmt.Printf("ss1: %p %d %d %[1]v\n", ss1, len(ss1), cap(ss1)) //ss1: 0xc042031da0 4 5 [7 0 0 1]
ss1 = append(ss1, s1...)
fmt.Printf("s1: %p %d %d %[1]v\n", s1, len(s1), cap(s1))     //s1: 0xc042031da0 3 5 [7 0 0]
fmt.Printf("ss1: %p %d %d %[1]v\n", ss1, len(ss1), cap(ss1)) //ss1: 0xc04205e0a0 7 10 [7 0 0 1 7 0 0]
}
##复制切片元素
Go 语言中除了可以进行引用形式的假拷贝,也可以使用 copy() 方法实现真拷贝:
copy() 方法的签名为:copy(dst, src)
拷贝后的数据与源切片毫无关联
可以进行完全拷贝或局部拷贝
*****
func main() {
//copy(dst,src)
s := []int{1, 2, 3, 4, 5}
fmt.Println("s:", s) //s: [1 2 3 4 5]
ss := make([]int, len(s))
fmt.Println("ss:", ss) //ss: [0 0 0 0 0]
copy(ss, s)
fmt.Println("ss:", ss) //ss: [1 2 3 4 5]
ss[0] = 9
fmt.Println("s:", s)   //s: [1 2 3 4 5]
fmt.Println("ss:", ss) //ss: [9 2 3 4 5]
sss := make([]int, 3)
copy(sss, s)
fmt.Println("s:", s)//s: [1 2 3 4 5]
fmt.Println("sss:", sss)//sss: [1 2 3]
}
阅读更多
版权声明:本文为博主原创文章,转载请加转载地址http://blog.csdn.net/williamfan21c|Copyright ©2011-2017,Supernatural, All Rights Reserved. https://blog.csdn.net/fanpengfei0/article/details/53481614
文章标签: go
个人分类: Golang
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭