Go语言学习之入门篇(七)

1.Go语言的静态数组和动态数组slice

Go语言支持两种数组,分别为静态和动态数组,我们同样用例子来感受这两种数组的用法

1.1 静态数组

我们先给出一个静态数组的声明方式

package main

import "fmt"

func main()  {
	// 声明一个静态数组array1,长度为10,默认前三个元素元素为1,2,3,其余为0
	array1  := [10]int{1, 2, 3}

	fmt.Println(array1)
}

运行结果

[1 2 3 0 0 0 0 0 0 0]

可以看到,Go语言中的数组的定义方式于java类似,且支持提供部分默认值的形式。静态数组的特点即为长度固定,声明时即开辟连续空间地址来存放数组,不可延长数组的长度

1.2 动态数组slice

熟悉python的列表或者java ArrayList类的小伙伴可能对这个并不陌生,因为slice和这两种类型很类似,Go语言的动态数组slice也被成为切片,所谓动态,即可以动态的添加元素,动态的分配内存地址且在传参的时候,传递的是地址而不是值拷贝。

package main

import "fmt"

func printArray(slice1 []int)  {
	// 不需要索引值,只需要每个元素的值
	for _,value := range slice1 {
		fmt.Println( "value=", value)
	}
}


func main()  {
	// 声明一个动态数组slice1,给了三个默认值1,2,3
	slice1  := []int{1, 2, 3}
	printArray(slice1)
}

运行结果

value= 1
value= 2
value= 3

以上是slice的简单用法,我们看看如果在函数中改变其中元素的值,动态数组和静态数组的区别:

package main

import "fmt"

func testArray(array1 [10]int)  {
	//改变其中一个元素的值
	array1[1] = 20
}

func testSlice(slice1 []int)  {
	//改变其中一个元素的值
	slice1[1] = 20
}

func main()  {
	// 声明一个长度为10的静态数组array1,给了三个默认值1,2,3
	array1  := [10]int{1, 2, 3}
	// 声明一个动态数组slice1,给了三个默认值1,2,3
	slice1  := []int{1, 2, 3}

	fmt.Println("before..........")
	fmt.Println(array1)
	fmt.Println(slice1)

	testArray(array1)
	testSlice(slice1)
	fmt.Println("after...........")
	fmt.Println(array1)
	fmt.Println(slice1)
}

运行结果:

before..........
[1 2 3 0 0 0 0 0 0 0]
[1 2 3]
after...........
[1 2 3 0 0 0 0 0 0 0]
[1 20 3]

可以看到,两个方法都尝试改变数组中第二个元素的值,但是我们可以看到,静态数组的值并没有发生变化,这是因为在传参的时候才用的值传递,传递过去的array1只是main中array1的副本,而动态数组slice1传递的是地址,也可以说是指向sclice内存地址的指针。所以传递过去后读其中值的修改在在回到mian函数中是有效的。

3.数组的遍历方式

package main

import "fmt"

func printArray(array [10]int)  {
	for index,value := range array {
		fmt.Println("index:", index, "value=", value)
	}
}


func main()  {
	// 声明一个静态数组array1,长度为10,默认前三个元素元素为1,2,3,其余为0
	array1  := [10]int{1, 2, 3}
	printArray(array1)
}

 运行结果:

index: 0 value= 1
index: 1 value= 2
index: 2 value= 3
index: 3 value= 0
index: 4 value= 0
index: 5 value= 0
index: 6 value= 0
index: 7 value= 0
index: 8 value= 0
index: 9 value= 0

在遍历数组的时候,会有两个返回值,分别是数组对应元素的索引和对应位置的值,有时候不需要数组的索引信息的时候,可以采用匿名的方式,这个与python十分相似。

package main

import "fmt"

func printArray(array [10]int)  {
	// 不需要索引值,只需要每个元素的值
	for _,value := range array {
		fmt.Println( "value=", value)
	}
}


func main()  {
	// 声明一个静态数组array1,长度为10,默认前三个元素元素为1,2,3,其余为0
	array1  := [10]int{1, 2, 3}
	printArray(array1)
}

运行结果:

value= 1
value= 2
value= 3
value= 0
value= 0
value= 0
value= 0
value= 0
value= 0
value= 0

对于动态数组,即切片的遍历方式与数组相同,这里不再演示。

值得注意的是,不同长度的静态数组代表的是不同类型。这里我们可以通过数组传参来感受

package main

import "fmt"

func printArray(array [20]int)  {
	// 不需要索引值,只需要每个元素的值
	for _,value := range array {
		fmt.Println( "value=", value)
	}
}


func main()  {
	// 声明一个静态数组array1,长度为10,默认前三个元素元素为1,2,3,其余为0
	array1  := [10]int{1, 2, 3}
	printArray(array1)
}

程序会报错,报错信息为

cannot use array1 (type [10]int) as type [20]int in argument to printArray

可以看到,长度为20的静态数组和长度为10的静态数组是完全不同的数据类型,不能兼容。

Go语言的切片还有很多声明方式,这里再列举一些。

首先,slice在声明的时候如果不给定一些默认值,那可其长度就为0,且为空

package main

import "fmt"

func main()  {
	// 声明一个动态数组slice1,
	var slice1 []int
	fmt.Println(len(slice1))
	fmt.Println(slice1)

}

运行结果:

0
[]
其次,也可以让系统预开辟一些空间,比如需要一个长度为3的slice

package main

import "fmt"

func main()  {
	// 声明一个动态数组slice1,
	slice1 := make([]int, 3)
	fmt.Println(len(slice1))
	fmt.Println(slice1)

}

运行结果:

3
[0 0 0]

这里使用make来创建了一个长度为3的slice,系统默认给每个值赋值为0,这里可能有小伙伴会混淆什么时候用var好,什么时候:=好,个人认为是只声明不赋值的情况下采用var,声明并赋值的话采用:=。

对于slice的其他用法,如添加元素和删除元素,将在下一节提到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值