Golang中的数组Array和切片Slice

数组

数组(Array)是类型相同元素的集合。不允许在一个数组使用不同类型的元素(比如:不允许整数和字符串一起使用)。

  • 数组长度是不可变的
  • 数组是值类型
  • 数组之间可以用== 或 !=比较(但是长度也是类型的一部分,长度不同,是两个不同类型,不能使用==和!=)
  1. 声明方式
//声明一个长度为3的整数类型。数组的所有元素都自动赋值为元素类型的0值
var a [3]int
fmt.Println(a) // [0 0 0]

var b [3]bool
fmt.Println(b) // [false false false]

//数组的索引是从0开始,所以a[1]是给第二个元素赋值
a[1] = 100
a[2] = 200
fmt.Println(a) // [0 100 200]

//速记声明,在数组类型后面加一对大括号{},在大括号里面写元素初始值列表,多个值用逗号分隔
c := [5]int{1, 2, 3, 4, 5}
fmt.Println(c)  // [1 2 3 4 5]

//通过下标赋值,默认赋值第一个元素,剩下的自动赋值0
d := [3]int{12}
fmt.Println(d) // [12 0 0]

// 赋值第三个元素
e := [3]int{2:12}
fmt.Println(e) // [0 0 12]

//使用省略号,让编译器自动推到长度
f := [...]int{12, 78, 50}
fmt.Println(f) // [12 78 50]

  1. 数组是值类型,如果数组的变量被赋值时,将会或者原来数组的copy,新数组中元素的改变不会影响原数组中元素的值
// 数组bb改变后没有影响aa
aa := [...]string{"THIS", "IS", "TEST", "ARRAY"}
bb := aa
bb[0] = "THAT"
fmt.Println("aa is ", aa) // aa is  [THIS IS TEST ARRAY]
fmt.Println("bb is ", bb) // bb is  [THAT IS TEST ARRAY]

//切片dd改变后影响了cc
cc := []string{"THIS", "IS", "TEST", "ARRAY"}
dd := cc
dd[0] = "THAT"
fmt.Println("cc is ", cc) // cc is  [THAT IS TEST ARRAY]
fmt.Println("dd is ", dd) // dd is  [THAT IS TEST ARRAY]
  1. 通过len()获取数组长度
aa := [...]string{"THIS", "IS", "TEST", "ARRAY"}
fmt.Println("aa length is ", len(aa)) // aa length is  4
  1. 数据遍历
aa := [...]string{"THIS", "IS", "TEST", "ARRAY"}

//使用 range遍历
for i, v := range aa {
	fmt.Printf("index= %d, value=%s\n", i, v)
}

// 使用len进行遍历
for i:=0; i< len(aa); i++ {
	fmt.Printf("index= %d, value=%s\n", i, aa[i])
}

// index= 0, value=THIS
// index= 1, value=IS
// index= 2, value=TEST
// index= 3, value=ARRAY

//如果只想获取数组的值,不需要数组的索引可以使用标识符"_"
for _, v := range aa {
	fmt.Printf("value=%s\n", v)
}

//指针数组(首先是个数组,数组的元素都是指针)
var pa [4]*string
for i,v := range aa {
	fmt.Printf("index= %d, value=%s\n", i, v)
	pa[i] = &aa[i]
}
// index= 0, value=THIS
// index= 1, value=IS
// index= 2, value=TEST
// index= 3, value=ARRAY
// [0xc00005e100 0xc00005e110 0xc00005e120 0xc00005e130]

//数组指针(首先是个指针,它只想一个数组)
var pa2 *[4]string
pa2 = &aa
fmt.Println(*pa2)
fmt.Println(pa2)
// [THIS IS TEST ARRAY]
// &[THIS IS TEST ARRAY]
  1. 多维数组
aaa := [3][2]string{
	{"1", "2"},
	{"11", "22"},
	{"111", "222"},
}

for _,v1 := range aaa {
	fmt.Printf("v1=%s\n", v1)
	for _,v2 := range v1 {
		fmt.Printf("v2=%s\n", v2)
	}
}

// v1=[1 2]
// v2=1
// v2=2
// v1=[11 22]
// v2=11
// v2=22
// v1=[111 222]
// v2=111
// v2=222

切片slice

切片不是数组,不存储任何元素,它是对数组的引用。切片比数组更为方便、灵活。
切片类型的字面量表示:

[] T :T是元素类型,比如:
[] int
[]string

  1. 切片的创建
//使用make创建切片
s := make([]string, 3)
fmt.Println("emp", s) // emp [  ]

s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("set", s) // set [a b c]
fmt.Println("set", s[2]) // set c
fmt.Println("set", len(s)) // set 3

var s2 = []int{1,2,3,4}
s3 := []int{1,2,3,4}
fmt.Println(s2)  // [1 2 3 4]
fmt.Println(s3) // [1 2 3 4]
  1. append添加元素

// 使用append追加元素
s = append(s, "d")
//使用len()获取长度,cap()获取容量
fmt.Println("length : ",len(s)) // length :  4

//如果添加过程中容量不够,则自动扩容,容量是在原来的基础上乘以2
fmt.Println("cap : ",cap(s)) // cap :  6 

s = append(s, "e", "f")
fmt.Println(s) //[a b c d e f]
s = append(s, "g")
fmt.Println("cap : ",cap(s)) // cap :  12 
  1. 修改切片
//修改切片会改变原来数据
darr := [...]int{57, 89, 90, 82, 100, 78, 67, 69, 59}
//含第三个元素,不含第6个元素
dslice := darr[2:5] 
fmt.Println("array before",darr) // array before [57 89 90 82 100 78 67 69 59]
for i := range dslice {
	dslice[i]++
}
fmt.Println("array after",darr) // array after [57 89 91 83 101 78 67 69 59]

//含第三个元素,不含第6个元素
sl := darr[2:5] 
fmt.Println(sl) // [90 82 100]

// 从开始到第5个元素(不含第6个)
sEnd := darr[:5] 
fmt.Println(sEnd) // [57 89 90 82 100]

// 从第3个到最后
sBegin := darr[2:]
fmt.Println(sBegin) // [90 82 100 78 67 69 59]


// 共享同一个底层数组时,对每一个切片的修改都会反映在底层数组中
dsilece1 := darr[:] // 从0到最后
dsilece2 := darr[:]

fmt.Println("array before change",darr) // array before change [57 89 90 82 100 78 67 69 59]
dsilece1[0] = 1
fmt.Println("array change 1",darr) // array change 1 [1 89 90 82 100 78 67 69 59]
dsilece2[1] = 2
fmt.Println("array change 2",darr) // array change 2 [1 2 90 82 100 78 67 69 59]
  1. 遍历和多维切片
var s2 = []int{1,2,3,4}
for _,v := range s2 {
	fmt.Println(v) // 1 2 3 4
}
slice3 := [][]string {
	{"C", "C++"},
	{"JavaScript"},
	{"Go", "Rust"},
}
for _, v1 := range slice3 {
	fmt.Printf("%s ", v1)
	for _, v2 := range v1 {
		fmt.Printf("%s ", v2)
		fmt.Printf("\n")
	}
}

// v1=[C C++]
// v2=C
// v2=C++
// v1=[JavaScript]
// v2=JavaScript
// v1=[Go Rust]
// v2=Go
// v2=Rust

平常使用切片比数组要多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值