Golang中make()创建的切片使用append时为何会基于长度值产生空条目
Golang中make()创建的切片使用append时为何会基于长度值产生空条目
str_slice := make([]string, 1)
str_slice = append(str_slice, "X")
str_slice = append(str_slice, "Y")
str_slice = append(str_slice, "Z")
for _, val := range str_slice {
anyThing = append(anyThing, val)
}
fmt.Println(anyThing)
len(str_slice) 的值为 4。如果我们在 make() 中将长度参数设置为 0,就不会出现这个问题。
在进行追加操作时,难道不能自动检测到它是空的并放置在第一个位置吗?在最新的 Go 版本中,是否有任何提案来改变这种行为?
更多关于Golang中make()创建的切片使用append时为何会基于长度值产生空条目的实战教程也可以访问 https://www.itying.com/category-94-b0.html
感谢 @skillian
更多关于Golang中make()创建的切片使用append时为何会基于长度值产生空条目的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果我想在Go中尽可能接近地匹配你的Python代码,我会这样写:
listString := []string{}
listString = append(listString, "abc")
listString = append(listString, "xyz")
fmt.Println(listString)
在
str_slice := make([]string,1)
之后,该切片并非空:它有一个条目,其值为字符串的“零”值 ""。
如果你想要一个空切片,可以尝试
str_slice := make([]string, 0, 1)
listString = [] 在 Python 中不等同于 listString = make([]string, 1),而更像是 listString = make([]string, 0)。
listString = make([]string, 1) 在 Go 中更类似于 Python 中的 listString = [""]。
这与是否为编译型语言无关。
是的,有道理,这就是为什么我提到如果在 make() 中指定 len=0 会有所不同。
Go 会使用该类型的默认值进行初始化。(这与 C 语言不同)
我想指出的是,当执行 append 操作时,为什么它不能覆盖第一个 "" 条目,并将 X 作为其第一个条目。
因为该元素可能特意是 "",而且检查它是否为随机值会产生运行时开销,这是某些人不希望看到的。
如果你想根据你对“空”的定义来覆盖那些看似是空值的先前条目,你需要添加自己的追加函数。
// 代码示例:自定义追加函数
func appendIfNotEmpty(slice []string, element string) []string {
if element != "" {
return append(slice, element)
}
return slice
}
在Go语言中,make([]T, length, capacity)创建的切片会根据length参数进行初始化。当你使用make([]string, 1)时,会创建一个长度为1、容量为1的切片,其中第一个元素是string类型的零值(空字符串"")。
问题出现在这里:
str_slice := make([]string, 1) // str_slice = [""]
str_slice = append(str_slice, "X") // str_slice = ["", "X"]
append()函数总是在切片的末尾追加元素,而不是在"空"位置。它不会检测元素是否为零值,因为零值在Go中是有效的值。
正确的做法是:
// 方法1:创建长度为0的切片
str_slice := make([]string, 0)
str_slice = append(str_slice, "X") // str_slice = ["X"]
// 方法2:使用字面量
str_slice := []string{"X"}
// 方法3:如果知道容量,可以指定容量但长度为0
str_slice := make([]string, 0, 10) // 长度为0,容量为10
str_slice = append(str_slice, "X")
关于你的第二个问题:Go语言团队不会改变这种行为,因为:
- 零值是有效的值,区分"空"和"零值"会增加复杂性
- 当前行为明确且一致:
append总是追加到末尾 - 这符合Go的设计哲学——简单和可预测
如果你需要覆盖第一个元素而不是追加,应该直接赋值:
str_slice := make([]string, 1)
str_slice[0] = "X" // 直接赋值,而不是append
或者使用索引操作:
str_slice := make([]string, 3)
str_slice[0] = "X"
str_slice[1] = "Y"
str_slice[2] = "Z"

