loops - 指针 slice 和循环

标签 loops pointers go slice

<分区>

我想这个问题问了好几次,但我还是很困惑:

我有以下代码:

type obj struct {
    s *string
}

var cmdsP = []*string {
    stringPointer("create"),
    stringPointer("delete"),
    stringPointer("update"),
}

var cmds = []string {
    "create",
    "delete",
    "update",
}

// []*string
func loop1() {
    slice := make([]obj, 0, 0)

    for _, cmd := range cmdsP {
        slice = append(slice, obj{cmd})
    }
    for _, o := range slice {
        fmt.Println(*o.s)
    }
}

// []string
func loop2() {
    slice := make([]obj, 0, 0)
    for _, cmd := range cmds {
        slice = append(slice, obj{&cmd})
    }
    for _, o := range slice {
        fmt.Println(*o.s)
    }
}

func stringPointer(v string) *string {
    return &v
}

https://play.golang.org/p/65Le_8Pi3Mi

唯一的区别在于 slice 语义 []*string[]string 它如何改变 cmd 变量的行为?您能否详细画出或解释一下在两次循环的迭代过程中内存中发生了什么?

最佳答案

当您在集合上调用 range 时,go 运行时会初始化 2 个内存位置;一个用于索引(在本例中为 _),一个用于值 cmd

然后 range 所做的是获取集合中的每个项目并将它们复制到它在调用 range 时创建的内存位置。

这意味着 slice 中的每一项都被一个一个地放入该内存位置。

当你执行 &cmd 时,你正在使用一个指针。该指针指向每个 slice 项被复制到的共享内存位置。

使用 &cmd 创建的所有指针都指向相同的内存位置。

这意味着在 range 完成后,您的指针指向的内存位置中唯一剩下的值是 range 迭代的最后一个值。

这就是你得到输出的原因

update
update
update

关于loops - 指针 slice 和循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51307254/

相关文章:

Haskell 中 ADT 的指针

C程序: Segmentation Fault

c - 指针和字符串操作

bash - 如何使用 Bash 遍历文件中的每一行?

javascript - 为什么 Javascript 函数在 php 循环中只执行一次?

python - 如何遍历字典并对其元素进行操作?

go - 当前用于 Google Dataflow 的 GoLang SDK 是否支持自动缩放和并行处理?

firebase - 编写云函数时如何避免循环?

go - Bazel 没有将 BUILD 文件添加到外部依赖项

algorithm - 以预定义比率循环遍历服务器的 Go 算法