Go——数组

Golang Array和以往认知的数组有很大的。

  • 数组是同一种数据类型的固定长度的序列。
  • 数组定义:var alen int,比如:var a 5int,数组长度必须是常量,且类型的组成部分。一旦定义,长度不能变。
  • 长度是数组类型的一部分,因此,var a5 int和var a10 int是不同的类型。
  • 数组可以通过下标进行访问,下标从0开始,最后一个元素下标是:len-1。
Go 复制代码
for i := 0; i < len(a); i++ {
    
}

for index, v := range a {

}
  • 访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic。
  • 数组是值类型,赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值。
  • 至此"==","!="操作符,因为内存总是被初始化过的。
  • 指针数组 n *T,数组指针 *nT。

1.数组初始化

  • 一维数组
Go 复制代码
package main

import (
	"fmt"
)

// 全局变量
var arr0 [5]int = [5]int{1, 2, 3} //未初始化元素值为0
var arr1 = [5]int{1, 2, 3, 4, 5}
var arr2 = [...]int{1, 2, 3, 4, 5, 6}           //通过初始化值来确定数组长度
var str = [5]string{3: "hello world", 4: "tom"} //通过引号初始化元素

func main() {
    //局部变量
	a := [3]int{1, 2}                          //未初始化元素值为0
	b := [...]int{1, 2, 3, 4, 5}               //通过初始化值来确定数组长度
	c := [5]string{3: "hello world", 4: "tom"} //通过引号初始化元素
	d := [...]struct {
		name string
		age  uint8
	}{
		{"user1", 10}, //可以省略元素类型
		{"user2", 20}, //不要忘记最后的逗号
	}

	fmt.Println(arr0, arr1, arr2, str)
	fmt.Println(a, b, c, d)
}
  • 多维数组
Go 复制代码
package main

import "fmt"

//全局变量
var arr0 [5][3]int
var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {4, 5, 6}}

func main() {
	//局部变量
	a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
	b := [...][2]int{{1, 2}, {3, 4}, {5, 6}} //第二维度不能为...
	fmt.Println(arr0, arr1)
	fmt.Println(a, b)
}

2. 数组值拷贝

数组是值类型,赋值和传参会复制整个数组,而不是指针。

值拷贝行为会造成性能问题,通常会建议使用slice,或数组指针。

Go 复制代码
package main

import "fmt"

func test(a [2]int) {
	fmt.Printf("test-a:%p\n", &a)
	a[0] = 100
	a[1] = 100
}

func main() {
	var a [2]int
	fmt.Printf("main-a:%p\n", &a)
	test(a)
	fmt.Println(a)
}

因为值拷贝,地址不同,数据有没有修改。

3. 内置函数

内置函数len和cap都返回数组长度(元素数量)

Go 复制代码
package main

import "fmt"

func main() {
	var arr [2]int = [2]int{1, 2}
	fmt.Println(len(arr), cap(arr))

	arr2 := [...][2]int{{1, 2}, {3, 4}} //二维数组,其中一维数组是它的元素
	fmt.Println(len(arr2), cap(arr2))
}

注意:string底层是byte数组(\[\]byte),len一个string类型的遍历,得到的是byte数组的长度。

4. 多维数组遍历

Go 复制代码
package main

import "fmt"

func main() {
	arr2 := [...][2]int{{1, 2}, {3, 4}} //二维数组,其中一维数组是它的元素
	//使用内置函数len
	for i := 0; i < len(arr2); i++ {
		for j := 0; j < len(arr2[i]); j++ {
			fmt.Printf("arr2[%d][%d] = %d ", i, j, arr2[i][j])
		}
	}
	fmt.Println()
	//使用range
	for index1, v1 := range arr2 {
		for index2, v2 := range v1 {
			fmt.Printf("arr2[%d][%d] = %d ", index1, index2, v2)
		}
	}
}

5. 数组拷贝和传参

使用指针传参。

6. 数组练习

  • 求数组所有元素之和
Go 复制代码
package main

import (
	"fmt"
	"math/rand"
	"time"
)

func sumArr(a [10]int) int {
	sum := 0
	for i, v := range a {
		fmt.Printf("arr[%d]=%d ", i, v)
		sum += v
	}
	fmt.Println()
	return sum
}

func main() {
	//随机数种子
	rand.Seed(time.Now().Unix())

	var b [10]int
	for i := 0; i < len(b); i++ {
		b[i] = rand.Intn(1000) //产生一个0到1000的随机数
	}

	sum := sumArr(b)
	fmt.Println(sum)
}
  • 找到数组中和为给定值的两元素下标
Go 复制代码
package main

import "fmt"

func myTest(arr [6]int, val int) {
	for i := 0; i < len(arr); i++ {
		for j := len(arr) - 1; j > i; j-- {
			if arr[i]+arr[j] == val {
				fmt.Printf("(%d, %d)", i, j)
			}
		}
	}
}

func main() {
	arr := [...]int{1, 2, 3, 4, 5, 6}
	myTest(arr, 8)
}
相关推荐
名字还没想好☜1 小时前
Go 的 select 实战:超时、非阻塞收发与优雅退出的三个套路
开发语言·数据库·golang·go·并发
编程序的员2 小时前
使用OpenTelemetry来监控GoLang应用
运维·golang·monitoring·apm·opentelemetry
ttwuai15 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
布朗克16819 小时前
Go 入门到精通-31-编码与序列化
开发语言·qt·golang·编码与序列化
microrain1 天前
从硬编码到热插拔:SagooIoT插件架构如何打破物联网平台的扩展瓶颈
物联网·golang·开源·sagooiot
geovindu1 天前
go:Backtracking Algorithm
开发语言·后端·算法·golang·回溯算法
qq_452396231 天前
第六篇:《并发编程核心:Goroutine 与 Channel》
golang
llwszx1 天前
【Java/Go后端手撸原生Agent(第五篇):多工具并行调用 + BashTool执行引擎 + Judge证据链升级】
java·后端·golang·状态机·pydantic·agnet·llm-as-judge
FfHUCisI1 天前
Go语言程序结构 —— 变量、声明与零值机制
golang
超人不会飞_Jay1 天前
Go课程2
开发语言·后端·golang