go - Go 中的切片如何不被取消引用?
问题描述
我已将问题作为注释包含在代码中。
我在这里看到不一致。我们在这里做 3 片。在第一个切片 s = s[:0] 之后,s 应该始终指向 s[:0]。
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
printSlice(s)
// Slice the slice to give it zero length.
//1
s = s[:0]
printSlice(s) //after we do this, should not the var s always point to s[:0]?
// Extend its length.
s = s[:4]
printSlice(s) //here, how is this s pointing back to original s? we just changed it to be s = s[:0]
// Drop its first two values.
s = s[2:] //yet here we somehow refer to only the portion from s[:4]
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
输出:
len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 [] // slice s[:0]
len=4 cap=6 [2 3 5 7] // slice s[:4] - here we refer to the whole array s
len=2 cap=4 [5 7] // slice s[2:] - here we refer not to the whole array s, but to the part we got from s[:4], which is contradiction to s[:0]
希望它不会太混乱。
解决方案
切片是底层数组的视图。无论您重新切片它,它仍然是相同的底层数组。如果你取同一个数组的两个切片,它们也将具有相同的底层数组,例如: https: //play.golang.org/p/T-hYDWeo2TK
initial := []string{"foo", "bar", "baz"}
s1 := initial[:1]
initial[0] = "qux"
fmt.Println(s1)
[曲克斯]
Go 博客文章Go Slices: usage and internals中的大量示例对此进行了详细解释:
切片是数组段的描述符。它由指向数组的指针、段的长度及其容量(段的最大长度)组成。
因此,您可以继续制作具有不同长度/容量/起始索引但具有相同数组的不同切片。它们只是同一阵列上的不同视图。
推荐阅读
- android - Jetpack 撰写新源无法正常工作
- haskell - 共享一个无点函数,但评估两次
- java - Spring Cloud Kubernetes 无法设置 ConfigMap 值
- r - 使用基于 ID 列的一列的串联可能值创建一列
- javascript - 如何从 vuejs 中的对象数组中跟踪更改的值
- javascript - 如何用对象中的键对数组进行分组?
- sql - 如何在此查询中打印学生姓名?
- c# - 当我尝试在 Xamarin 中启动模拟器时,我收到“构建已取消”消息
- c# - 在没有模拟实现的情况下调用 Moq 验证方法
- python - MySQL 从 python 插入/更新,数据来自 excel 电子表格