arrays - 迭代时更改值

标签 arrays for-loop go

假设我有这些类型:

type Attribute struct {
    Key, Val string
}
type Node struct {
    Attr []Attribute
}

并且我想迭代节点的属性以更改它们。

我希望能够做到:

for _, attr := range n.Attr {
    if attr.Key == "href" {
        attr.Val = "something"
    }
}

但是因为 attr 不是一个指针,所以这是行不通的,我必须这样做:

for i, attr := range n.Attr {
    if attr.Key == "href" {
        n.Attr[i].Val = "something"
    }
}

有没有更简单或更快的方法?是否可以直接从 range 获取指针?

显然,我不想仅仅为了迭代而更改结构,更冗长的解决方案不是解决方案。

最佳答案

不,你想要的缩写是不可能的。

这样做的原因是 range 从您正在迭代的 slice 中复制值。 specification about range说:

Range expression                          1st value             2nd value (if 2nd variable is present)
array or slice  a   [n]E, *[n]E, or []E   index    i  int       a[i]       E

因此,range 使用 a[i] 作为数组/slice 的第二个值,这实际上意味着 复制值,使原始值不可触及。

following code 演示了此行为:

x := make([]int, 3)

x[0], x[1], x[2] = 1, 2, 3

for i, val := range x {
    println(&x[i], "vs.", &val)
}

该代码为您打印范围内的值和实际值的完全不同的内存位置 slice 中的值:

0xf84000f010 vs. 0x7f095ed0bf68
0xf84000f014 vs. 0x7f095ed0bf68
0xf84000f018 vs. 0x7f095ed0bf68

所以你唯一能做的就是使用指针或索引,正如 jnml 和 peterSO 已经提出的那样。

关于arrays - 迭代时更改值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57735927/

相关文章:

c++ - 在对象数组的每个索引上调用不同的构造函数

arrays - 无法将数据输入到类模型(swift)

java - 将 Java 数组中任意范围的元素设置为 null 的最快方法是什么?

perl - 在 HTML::Element 的 Look_down 例程 Perl 中指定多个类?

go - 如何使用 gocql 优化 scylla db 的交叉分片查询

javascript - 在 JavaScript 中将数组对象转换为数组数组

java - Java中循环语句的垃圾收集

Java直接遍历数组而不是数组变量

google-app-engine - 如何根据项目ID设置变量?

Gocql 自定义编码器