在我看来,段在声明时并不是被创建的,可能是因为我开始学习《Head First》的那本书。Learning Go » 2020 ISBN 978-5-4461-1395-8(第 210 页)以下是其中的内容:
但我发现一切都是这样的:
package main
import "fmt"
func main() {
var strArr []string
fmt.Print(strArr)
strArr = append(strArr,"qwerty")
fmt.Print(strArr)
}
结果:
[][qwerty]
...Program finished with exit code 0
Press ENTER to exit console
事实证明,我的信息已经过时,而且这本书是旧版本,或者我弄错了什么。根据我给出的例子,当声明一个段时,它仍然会自动创建,这是真的吗?
当变量在没有初始化器的情况下声明时,它会被赋值
zero value
。对于切片来说,这是nil
. 您的示例之所以有效,是因为内置函数len
,range
并且append
可以使用 nil 参数正常工作。示例: https: //go.dev/play/p/c35hkN_vVbY
结果:
更新
关于
empty := []int{}
和var empty []int; empty = make([]int,0)
该包
reflect
(目前)包含一个结构体SliceHeader
,它实际上是运行时的一个切片:它由三个字段组成:指向数据的指针、切片的长度以及该字段所指向的内存块的大小
Data
。让我们看看空切片
empty := []int{}
和是如何var empty []int; empty = make([]int,0)
:结果: https: //go.dev/play/p/8puJZ_wTFhJ
在这两种情况下,它都是某种指针,零长度和零容量。当然,指向零长度内存位置的指针看起来很奇怪,但对于垃圾收集器来说可能是必要的。
append
分配内存后,指针发生变化:结果: https: //go.dev/play/p/yoq-owhbb00
“空”切片的两个版本的行为相同。因此,我们可以假设这些初始化选项是等效的。
我对什么是“段”有点困惑。据我了解,这是切片的翻译。好像通常翻译成“切片”。
现在进入正题。这是代码
它给出了这个结果
那些。当变量被声明时,它被初始化为空值。如果计划使用这个特定的片段,那么通过make分配内存是有意义的。简单来说, append(不涉及复杂的实现)需要两个切片,确定需要多少内存来放置这两个切片中的数据并分配该内存,然后复制数据。
那些。在您的示例中,首先声明一个空切片,然后将数据附加到它。总的来说,一切都很正常——事情应该是这样的。您可能误解了书中的信息。