知识点:切片经过n次append,当某次append元素时,计算出的切片需占用长度超过当前容量,会发生扩容,创建新的底层数组,append函数返回的是 指向新底层数组的新切片 。
避坑:切片扩容后,新创建底层数组,元素拷贝到新的存储地址,使用扩容前获取到的元素指针做更新操作,实际更新的旧底层数组旧切片, 不会更新到新切片中,应使用元素在切片中的索引进行更新。
场景举例:给定切片s1存储n1个struct元素,切片s2存储n2个struct元素,strName="a"。要求:重新计算s1中Name==strName的元素的Age值(假设计算Age需等到第1步完成才能计算)
1. 将s2的元素存储到s1中。
2. 根据某算法计算oPerson.Age,并更新到切片中的此元素
错误实现:
package main
import "fmt"
type Person struct {
Name string
Age int
}
func CulAget() int {
return 18
}
func main() {
var s1 = []Person{
{
Name: "a",
Age: 10,
},
{
Name: "b",
Age: 11,
},
{
Name: "c",
Age: 12,
},
}
var s2 = []Person{
{
Name: "d",
Age: 13,
},
{
Name: "e",
Age: 13,
},
}
var strName = "a"
var oPerson *Person
for i, tmp := range s1 {
if tmp.Name == strName {
oPerson = &s1[i]
break
}
}
for _, oPerson2 := range s2 {
s1 = append(s1, oPerson2)
}
oPerson.Age = CulAget()
fmt.Println(oPerson) //&{a 18}
fmt.Println(s1) //[{a 10} {b 11} {c 12} {d 13} {e 13}]
}
正确实现:获取到符合要求的元素所在切片中的索引,根据索引更新切片对应位置的元素
package main
import "fmt"
type Person struct {
Name string
Age int
}
func CulAget() int {
return 18
}
func main() {
var s1 = []Person{
{
Name: "a",
Age: 10,
},
{
Name: "b",
Age: 11,
},
{
Name: "c",
Age: 12,
},
}
var s2 = []Person{
{
Name: "d",
Age: 13,
},
{
Name: "e",
Age: 13,
},
}
var strName = "a"
var index int = 0
for i, tmp := range s1 {
if tmp.Name == strName {
index = i
break
}
}
for _, oPerson2 := range s2 {
s1 = append(s1, oPerson2)
}
s1[index].Age = CulAget()
fmt.Println(s1) //[{a 18} {b 11} {c 12} {d 13} {e 13}]
}