【从零开始学习Go语言】Go语言的数组与切片引用类型与值类型
- 一.数组
- 二.多维数组
- 三.切片
- 四.值类型与引用类型
一.数组
go语言的数组在之前的一些例子中有引用过,go的数组在创建时需要声明存储数据的类型,长度,并且长度在确定后便不可增加,类似python中的元组
- 数组的声明方式有多种:
- 第一种
package main
import (
"fmt"
)
func main() {
var array [10]int //创建并初始化默认值为0,长度为10
fmt.Println(array) //这里打印可以看到输出的数组全部都是10
array[0]=1 //[]中的是索引
array[1]=2
array[2]=3
//···
fmt.Println(array) //这里输出就发现内容的值已经被填充,当然还有更简单的方法做这非常简单的操作,这里只是基础的解释
}
- 第二种
package main
import (
"fmt"
)
func main() {
var arr = [3]int{1,2,3} //使用var创建名称为arr的数组,arr的类型是什么取决于=后面的表达式,使用此方法可直接初始化并赋值
fmt.Println(arr)
}
- 第三种
package main
import (
"fmt"
)
func main() {
arr := [5]int{1, 2, 3, 4, 5} //简单方法声明,不过注意这种声明变量的方法只能用在方法内部
//比如现在的arr是在main的内部,如在外部也就是和package平级
//下需要使用var命名,了解js的应该更容易理解,与作用域相似
fmt.Println(arr)
}
- 第四种
有时数组传入的参数可能不确定或经常需要修改,每次都需要修改长度可能感觉很麻烦,这时就可以使用下面的方法啦,注意这里的修改不是添加,而是初始化的参数
package main
import (
"fmt"
)
func main() {
var arr = [...]int{1,2,3} //这里的三个...根据传入的参数长度而确定数组的长度,从而不必每次都修改长度
fmt.Println(arr)
}
二.多维数组
所谓多维数组或二维数组,其实就是一个数组中嵌套另一个数组,注意数组设置的长度不包括二维数组或多维数组的长度。结构大概如下:
代码演示:
//二维数组
package main
import (
"fmt"
)
func main() {
arr := [2][3]int{ //2是包含两个数组,3是每个数组长度为3
{1, 2, 4},
{1, 2}}
fmt.Println(arr) [[1 2 4] [1 2 0]]
fmt.Println(arr[0]) [1 2 4]//打印第一个数组,索引为0
fmt.Println(arr[0][2]) 4//取出索引为0的数组并搜索其中索引为2的数字:4
}
三.切片
数组的长度是固定且不课修改的,而切片的表达方式与数组基本一样,但大小不做限制,类似python中的数组
package main
import (
"fmt"
)
func main() {
arr := []int{1, 2, 3, 4, 5, 6}
fmt.Println(arr)
}
不填写长度就是切片啦,不过这里注意一点,切片的长度第一次初始化是根据所传入参数长度确认,第二次是根据第一次传入的参数长度为基准,话有点绕,下面演示个例子
package main
import (
"fmt"
)
func main() {
arr := []int{1, 2, 3, 4, 5, 6}
fmt.Println(cap(arr)) //6;cap查看的是切片的空间大小,也就是这个比如数组的长度设置了长度为10,实际使用了3,len返回的是3,而cap是10
arr = append(arr, 1, 2, 3)
fmt.Println(cap(arr)) //12;当切片长度增加,go会根据这个切片的原始长度叠加,假如第二次添加的数据没有达到12,它是不会再次叠加的
}
四.值类型与引用类型
- 这里用一个例子来介绍吧:
package main
import (
"fmt"
)
func main() {
//值类型
fmt.Println("\n---------------值类型-------------------------")
arr := [...]int{1, 2, 3, 4}
a := arr
fmt.Printf(" arr原值:%d,a原值:%d \n", arr, a)
a[1] = 5
fmt.Printf(" arr的值:%d \n arr的内存地址:%p \n a的值:%d \n a的内存地址:%p", arr, &arr, a, &a)
//引用类型
fmt.Println("\n---------------引用类型-------------------------")
array := []int{1, 2, 3, 4}
b := array
fmt.Printf(" array原值:%d,b原值:%d \n", array, b)
b[1] = 5
fmt.Printf(" array的值:%d \n array的内存地址:%p \n b的值:%d \n b的内存地址:%p", array, &array, b, &b)
}
返回:
---------------值类型-------------------------
arr原值:[1 2 3 4],a原值:[1 2 3 4]
arr的值:[1 2 3 4]
arr的内存地址:0xc00001c1c0
a的值:[1 5 3 4]
a的内存地址:0xc00001c1e0
---------------引用类型-------------------------
array原值:[1 2 3 4],b原值:[1 2 3 4]
array的值:[1 5 3 4]
array的内存地址:0xc00000c080
b的值:[1 5 3 4]
b的内存地址:0xc00000c0a0