Go 数组和切片

数组和切片

1.数组

(1)数组的定义

var arr1 [3]int = [3]int{1,2,3}
var arr2 = [3]int{1,2,3}
var arr3 = [...]int{1,2,3}
var arr4 = [...]int{0: 1, 1: 2, 2: 3}

(2)数组的遍历

func main() {
	arr := [...]int{1,2,3}
	//法一
	for i:=0;i<len(arr);i++ {
		fmt.Println(arr[i])
	}
	//法二
	for i,v := range arr {
		//i:索引	v,arr[i]:值
		fmt.Println(i,v,arr[i])
	}
}

2.切片

一个动态变化的数组

(1)切片的定义

//法一
arr := [...]int{1, 2, 3}
slice1 := arr[0:3]//左含右不含
fmt.Println(slice1)
//法二
var slice2 []int = make([]int,5,6)//5:长度 6:容量
fmt.Println(slice2)
//法三,同定义数组,但不用声明长度
var slice3 []int = []int{1,2,3}
fmt.Println(slice3)

(2)切片的遍历

func main() {
	var slice []int = make([]int,5,6)//5:长度 6:容量
	slice[0] = 0
	slice[1] = 1
	slice[2] = 2
	for i:=0;i<len(slice);i++ {
		fmt.Print(slice[i])
	}
	fmt.Println()
	for i, v := range slice {
		fmt.Println(i,v)
	}
}
/*
01200
0 0
1 1
2 2
3 0
4 0
*/

(3)切片的使用

  • 切片可以动态增长

  • 使用数组初始化时,左含右不含

  • var slice = arr[0:end] --> var slice = arr[:end]

  • var slice = arr[start:len(arr)] --> var slice = arr[start:]

  • var slice = arr[0:len(arr)] --> var slice = arr[:]

  • 切片可以继续切片

    func main() {
    	var slice1 []int = []int{1,2,3}
    	var slice2 = slice1[1:2]
    	fmt.Println(slice2)//[2]
    }
    
  • append内置函数,动态追加

    func main() {
    	var slice []int = make([]int, 2, 3)
    	fmt.Println(slice)
    	slice = append(slice, 1)
    	fmt.Println(slice)
    }
    /*
    [0 0]
    [0 0 1]
    */
    
  • 切片的拷贝

    //拷贝的切片创建新的独立空间
    var slice1 []int = make([]int, 2)
    var slice2 []int = make([]int, 2)
    copy(slice1,slice2)
    

(4)切片储存方式

切片类似于指针,是在内存中直接切出一块独立空间(cap),然后在该空间内存储内容(len)。

举个例子:

func main() {
	var s []int = make([]int, 2, 3)
	fmt.Println(s, len(s), cap(s))
}
//[0 0] 2 3

此时,数据存储方式如下图

append一个数据

func main() {
	var s []int = make([]int, 2, 3)
	s = append(s, 1)
	fmt.Println(s, len(s), cap(s))
}
//[0 0 1] 3 3

继续append

func main() {
	var s []int = make([]int, 2, 3)
	s = append(s, 1)
	s = append(s, 2)
	fmt.Println(s, len(s), cap(s))
}
//[0 0 1 2] 4 6

在这里插入图片描述

当切片的容量不足以继续append时,会自动增加容量。 在切片的容量小于 1000 个元素时,会成倍地增加容量。当元素个数超过 1000,会每次增加 25%的容量(随着语言的演化,这种增长算法可能会有所改变)。

这次,我们观察数组,根据该数组生成的切片,继续切片得到的切片,以及copy的切片之间的关系

func main() {
	var arr = [3]int{1, 2, 3}
	var s1 = arr[0:]
	var s2 = s1[1:]
	var s3 []int = make([]int, 3)
	copy(s3, s1)
	s2[1] = 9
	fmt.Println(arr)
	fmt.Println(s1, len(s1), cap(s1))
	fmt.Println(s2, len(s2), cap(s2))
	fmt.Println(s3, len(s3), cap(s3))
}

/*
[1 2 9]
[1 2 9] 3 3
[2 9] 2 2
[1 2 3] 3 3
*/

可见arr,s1,s2使用的其实是同一个数据,s3使用的是独自的数据

可见,切片可以理解为指针,指向一块单独为该切片开辟的空间,且该空间可以扩大,可以被其他指针指向。

参考资料:【尚硅谷】Golang入门到实战教程丨一套精通GO语言

<think>首先,用户的问题是:“golang 数组切片”,翻译成英文是“Golang array take slice”。我需要用中文回答这个问题。问题似乎是关于如何在Go语言中从数组获取切片。 关键点是: - 使用中文回答问题。 - 回答后,必须提出3-5个相关问题。 - 相关问题必须以“§§相关问题§§”开头,且在第一行完整输出。 - 禁止换行分散,意思是相关问题的列表应该紧凑,没有额外的换行。 - 最后,所有内容必须符合规则,否则回答无效。 回顾示例格式: - 首先,回答问题的内容。 - 然后,输出“§§相关问题§§”,紧接着是相关问题列表,如“1. ··· 2. ··· 3. ···”,没有换行分散。 所以,我的回答结构应该是: 1. 解释如何在Go中从数组获取切片。 2. 以中文回答。 3. 结束时,输出“§§相关问题§§”,然后列出3-5个相关问题。 现在,内容部分: - 在Go中,数组是固定大小的,切片是动态大小的视图。 - 要从数组获取切片,可以使用切片操作符:`array[start:end]`,其中startend是索引。 - 例如:`arr := [5]int{1,2,3,4,5}`,然后 `slice := arr[1:4]` 会得到 `[2,3,4]`。 - 解释基本概念。 确保回答简洁明了。 然后,提出相关问题: - 相关问题应该基于用户的问题我的回答。 - 用户的问题是“golang 数组切片”,所以相关问题可能涉及: 1. 切片数组的区别。 2. 如何修改切片影响原数组。 3. 切片的基本操作。 4. 性能考虑。 5. 常见错误。 列出3-5个: 1. Go语言中数组切片的主要区别是什么? 2. 如何从切片创建新的切片? 3. 修改切片会影响原始数组吗?为什么? 4. 在Go中,切片的容量长度如何工作? 5. 如何避免在切片操作中出现索引越界错误? 确保问题是相关的。 最后,输出格式: - 回答内容。 - 然后,直接“§§相关问题§§”后跟问题列表,例如: §§相关问题§§ 1. ... 2. ... 3. ... 没有额外的换行。 编写回答: - 先用中文解释。 - 可能包括一个简单的代码示例,因为用户提到了“golang”,类似于示例中的Python代码。 - 示例格式有代码块,所以我应该包括一个Go代码示例。 用户问题:“golang 数组切片”,所以重点是操作。 代码示例: ```go package main import "fmt" func main() { // 定义一个数组 arr := [5]int{1, 2, 3, 4, 5} // 从数组切片 slice := arr[1:4] // 索引从1开始到4(不包括4),所以是元素2,3,4 fmt.Println(slice) // 输出: [2 3 4] } ``` 在回答中包括这个。 然后结束。</think>在 Go 语言中,数组是固定大小的序列,而切片是动态大小的视图,可以基于数组创建。要从数组获取切片,使用切片操作符 `[start:end]`,其中 `start` 是起始索引(包含),`end` 是结束索引(不包含)。索引从 0 开始,如果省略 `start` 则默认为 0,省略 `end` 则默认为数组长度。切片是引用类型,修改切片会影响原数组。 示例代码: ```go package main import "fmt" func main() { // 定义一个数组 arr := [5]int{10, 20, 30, 40, 50} // 从数组切片:索引1到3(不包含3) slice := arr[1:3] fmt.Println(slice) // 输出: [20 30] // 修改切片会影响原数组 slice[0] = 99 fmt.Println(arr) // 输出: [10 99 30 40 50] } ``` 在这个例子中,`arr[1:3]` 创建了一个包含原数组索引 1 2 元素的切片切片共享底层数组数据,因此对切片的修改会反映到原数组上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值