【go语言学习笔记】数组和切片

1.数组

go语言中也配有数组这种数据结构,它的定义方式类似java,每一种定义都是一种类型,比如:
var arr [50]intvar arr [100]int,他们分别是[50]int类型和[100]int类型。

可以使用迭代器来遍历数组。

demo:

package main

import "fmt"

func main() {
	// 数组,同一个类型的集合
	var arr [50]int

	//操作数组,通过下标,从0开始到len-1

	// 一般for循环写法
	for i := 0; i < len(arr); i++ {
		arr[i] = i * 2
		fmt.Println(arr[i])
	}

	//迭代器写法
	for i := range arr {
		arr[i] = i
	}

	for i := range arr {
		fmt.Println(arr[i])
	}
}


2.二维数组

定义方式同上。
demo:

package main

import "fmt"

func main() {
	// 二维数组
	var a [3][4]int

	fmt.Println("a = ", a)
}

3.切片的创建

切片的底层是结构体,这里的切片类似c++中的引用,只是把底层数组(原数组)某段地址拷贝过去了,并没有创建新的数组。

定义方式:

  1. 直接定义,类似python的列表切片
  2. 借助make函数,make(切片类型,长度,容量)
package main

import "fmt"

func main() {
	//自动推导类型,同时初始化
	s1 := []int{1, 2, 3, 4}
	fmt.Println("s1 = ", s1)

	//借助make函数, make(切片类型,长度, 容量)
	s2 := make([]int, 5, 10)
	fmt.Println("len = ", len(s2), "cap = ", cap(s2))
	//没有指定容量,容量和长度一样
	s3 := make([]int, 5)
	fmt.Println("len = ", len(s3), "cap = ", cap(s3))
}

4.切片的截取

这里的截取类似python的切片,也是得到原数组的地址引用。

package main

import "fmt"

func main() {
	arr := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	//[low:high:max] 取下标从low开始至high-1的元素
	s1 := arr[:] //取整个数组
	fmt.Println("s1 = ", s1)

}


5.切片和数组的区别

数组[]里面的长度是一个固定常量,数组不能修改长度,len和cap固定,而切片,[]里面为空,或者…,切片的长度或容量可以不确定。
直接定义的切片像是动态扩容数组的替代品。

package main

import "fmt"

func main() {
	//切片和数组的区别
	//数组[]里面的长度是一个固定常量,数组不能修改长度,len和cap固定
	a := [5]int{}
	fmt.Println("len = ", len(a), " cap = ", cap(a))

	//切片,[]里面为空,或者...,切片的长度或容量可以不确定
	b := []int{}
	fmt.Println("len = ", len(b), "cap = ", cap(b))

	b = append(b, 11)
	fmt.Println("len = ", len(b), "cap = ", cap(b))

}


6.切片做函数参数

这样传入的切片像是引用传递,而不是数组的值传递,这样可以提高效率,节约内存。

package main

import "fmt"
import "math/rand"
import "time"

func InitData(s []int) {
	//设置随机种子
	rand.Seed(time.Now().UnixNano())

	for i := 0; i < len(s); i++ {
		s[i] = rand.Intn(100)
	}
}

func BubbleSort(s []int) { //传入一个数组的引用,,相当于传指针
	n := len(s)

	for i := 0; i < n-1; i++ {
		for j := 0; j < n-i-1; j++ {
			if s[j] > s[j+1] {
				s[j], s[j+1] = s[j+1], s[j]
			}
		}
	}
}

func main() {
	n := 10

	// 创建一个切片,len = n
	s := make([]int, n)

	InitData(s) //初始化数组
	BubbleSort(s)
	fmt.Println("s = ", s)
}


7.数组的比较和赋值

go语言支持数组的比较和赋值,但只支持==!=,他会逐个比较每个元素是否值一样,并且数组类型要相同才能比较和赋值,比如[50]int类型和[100]int类型就不能比较和赋值,因为他们不是同一个类型。

package main

import "fmt"

func main() {
	// 支持比较,只支持 == 或 !=, 比较是不是每一个元素都一样,2个数组比较,数组类型要一样
	// 比如 [5]int 和 [6]int就不是一个类型

	a := [5]int{1, 2, 3, 4, 5}
	b := [5]int{1, 2, 3, 4, 5}
	c := [5]int{1, 2, 3}
	fmt.Println("a == b", a == b)
	fmt.Println("a == c", a == c)

	// 同类型的数组可以赋值
	var d [5]int
	d = a
	fmt.Println("d = ", d)

	// 自动推导长度
	e := [...]int{1, 2, 3, 4}
	fmt.Println("e = ", e, "len(e) = ", len(e))
}


8.数组的初始化

这里的初始化类似c语言中的初始化,并加入了指定位置初始化,若是只初始化部分元素,未显式初始化的其他元素都会被初始化为0。

package main

import "fmt"

func main() {
	//1. 全部初始化
	var a [5]int = [5]int{1, 2, 3, 4, 5}
	fmt.Println("a = ", a)

	b := [6]int{1, 2, 3, 4, 5, 6}
	fmt.Println("b = ", b)

	//2. 部分初始化,没有初始化的元素自动赋值为0
	c := [5]int{1, 2, 3}
	fmt.Println("c = ", c)

	//3. 指定元素初始化
	d := [5]int{2: 3, 4: 6}
	fmt.Println("d = ", d)
}


9.数组的切片

数组切片 [low:high:max],是原数组的引用,其中的参数意义如下

  • low: 下标的起点
  • high: 下标的终点,不包括该下标,左闭右开
  • max:为切片保留的原切片的最大下标(不含max)
  • cap : max - low 容量,因为切片是原数组的引用,所以用max减去起始的指针,就是引用数组的容量。
package main

import "fmt"

func main() {
	a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 10}

	//数组切片 [low:high:max],是原数组的引用
	// low: 下标的起点
	// high: 下标的终点,不包括该下标,左闭右开
	// max:为切片保留的原切片的最大下标(不含max)
	// cap : max - low 容量,因为切片是原数组的引用,所以用max减去起始的指针,就是引用数组的容量
	slice := a[1:3:5]

	fmt.Println("slice = ", slice)
	fmt.Println("len(slice) = ", len(slice))
	fmt.Println("cap(slice) = ", cap(slice))
}

发布了128 篇原创文章 · 获赞 20 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u011544909/article/details/95039578