golang 数组切片(二)

本文介绍了Go语言中多维数组的使用方法,包括多维静态数组和动态数组的创建及操作方式。通过实例展示了如何避免在函数间传递数组带来的性能问题,并探讨了切片在多维数组操作中的应用。

多维数组介绍

1、多维静态数组
array := [][]byte{}

在函数中传递数组是非常昂贵的行为,因为在函数之间传递变量永远是传递值,所以如果变量是数组,那么意味着传递整个数组,即使它很大很大很大。。。
举个栗子,创建一个有百万元素的整形数组,在64位的机器上它需要8兆的内存空间,来看看我们声明它和传递它时发生了什么:
复制代码 代码如下:

var array [1e6]int
foo(array)
func foo(array [1e6]int) {

}

每一次 foo 被调用,8兆内存将会被分配在栈上。一旦函数返回,会弹栈并释放内存,每次都需要8兆空间。
Go 语言当然不会这么傻,有更好的方法来在函数中传递数组,那就是传递指向数组的指针,这样每次只需要分配8字节内存:
复制代码 代码如下:

var array [1e6]int
foo(&array)
func foo(array *[1e6]int){

}
但是注意如果你在函数中改变指针指向的值,那么原始数组的值也会被改变。幸运的是 slice(切片)可以帮我们处理好这些问题,来一起看看。

2、多维动态数组
slice := [][]byte{}

创建二维数据组

    slic := [][]int{{10}, {21, 22}}
    fmt.Println("slic", slic)
    fmt.Println("slic[0]:", slic[0])
    fmt.Println("slic[1]:", slic[1])
    fmt.Println("slic[0][0]", slic[0][0])

运行结果:

    slic [[10] [21 22]]
    slic[0]: [10]
    slic[1]: [21 22]
    slic[0][0] 10
    成功: 进程退出代码 0.

append()方法,比如我们现在对 slice[0] 增加一个元素,由于slice[0]分配空间已满需重新分配,则重建slice[0];slice[1]不受影响

func MulitSliceAppend() {
    S_0 := []int{11}
    S_1 := []int{20, 21}
    M_Slice := [][]int{S_0, S_1}
    fmt.Println("初始化   ", ":M_Slice", M_Slice)
    S_0[0] = 10
    fmt.Println("S_0 更改", ":M_Slice", M_Slice)
    fmt.Println("---------------------------------------------------------")
    M_Slice[0] = append(M_Slice[0], 11)
    fmt.Println("Append  ", ":M_Slice", M_Slice)
    S_0[0] = 11
    S_1[0] = 11
    fmt.Println("S_0 1更改", ":M_Slice", M_Slice)
}

运行结果:

初始化    :M_Slice [[11] [20 21]]
S_0 更改 :M_Slice [[10] [20 21]]
---------------------------------------------------------
Append   :M_Slice [[10 11] [20 21]]
S_0 1更改 :M_Slice [[10 11] [11 21]]
成功: 进程退出代码 0.

通过上述操作可以看到,若未重新分配地址,更改初始化切片时,多维切片值也会随之相应的变化;对slice[0]Append之后,对S_0值更改slice[0]不随之变化,说明slice[0]重新分配;对S_1值更改slice[1]随之变化,说明slice[1]未重新分配。

参考:
http://www.jb51.net/article/56828.htm

<think>首先,用户的问题是:“golang 数组切片”,翻译成英文是“Golang array take slice”。我需要用中文回答这个问题。问题似乎是关于如何在Go语言中从数组获取切片。 关键点是: - 使用中文回答问题。 - 回答后,必须提出3-5个相关问题。 - 相关问题必须以“§§相关问题§§”开头,且在第一行完整输出。 - 禁止换行分散,意思是相关问题的列表应该紧凑,没有额外的换行。 - 最后,所有内容必须符合规则,否则回答无效。 回顾示例格式: - 首先,回答问题的内容。 - 然后,输出“§§相关问题§§”,紧接着是相关问题列表,如“1. ··· 2. ··· 3. ···”,没有换行分散。 所以,我的回答结构应该是: 1. 解释如何在Go中从数组获取切片。 2. 以中文回答。 3. 结束时,输出“§§相关问题§§”,然后列出3-5个相关问题。 现在,内容部分: - 在Go中,数组是固定大小的,切片动态大小的视图。 - 要从数组获取切片,可以使用切片操作符:`array[start:end]`,其中start和end是索引。 - 例如:`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、付费专栏及课程。

余额充值