修改后的切片元素无法通过地图访问。我究竟做错了什么?
Modified slice elements not accessible with map. What am I doing wrong?
我有一个或多或少复杂的结构的切片,我希望这个切片的所有元素都可以通过映射访问。该映射包含指向切片元素的指针。我现在的问题是,当我更改切片元素的内容时,它不会反映在指向该元素的映射中。 IE。如果我从切片访问更改的元素,我会看到更改。但是,如果我从地图访问该元素,则看不到更改。
我制作了一个抽象代码示例,您可以在下面找到它。在这里它变得更加奇怪,因为我看到一个元素发生了变化,尽管所有元素都应该改变。
package main
import "fmt"
type Test struct {
one int
two *string
}
type List []Test
type MapToList map[int]*Test
func MakeTest() (t List, mt MapToList) {
t = []Test{}
mt = make(map[int]*Test)
var one, two, three string
one = "one"
two = "two"
three = "three"
t = append(t, Test{1, &one})
mt[1] = &t[len(t)-1]
t = append(t, Test{2, &two})
mt[2] = &t[len(t)-1]
t = append(t, Test{3, &three})
mt[3] = &t[len(t)-1]
return
}
func (s *List) Modify() {
for index := range *s {
var str string = "xxx"
(*s)[index].two = &str
}
}
func main() {
t, mt := MakeTest()
fmt.Println("Orginal")
for index := range t{
fmt.Println(index, t[index].one, *t[index].two)
}
t.Modify()
fmt.Println("Modified List")
for index := range t{
fmt.Println(index, t[index].one, *t[index].two)
}
fmt.Println("Modified Map")
for key, value := range mt {
fmt.Println(key, value.one, *value.two)
}
}
输出为:
Orginal
0 1 one
1 2 two
2 3 three
Modified List
0 1 xxx
1 2 xxx
2 3 xxx
Modified Map
1 1 one
2 2 two
3 3 xxx
我会一直在切片和映射中使用指针。这简化了很多。
当您使用值切片时,碰巧 &t[i]
在 append
操作之后变成指向旧的废弃切片中的元素的指针。当您访问它时,您正在访问旧切片的元素。因此 map 正在引用旧切片的元素。
使用指针解决了这个问题,因为每个 Test
结构只有一个副本,并且有多个指向它们的指针。指针在旧切片、新切片或映射中并不重要。
package main
import "fmt"
type Test struct {
one int
two *string
}
type List []*Test
type MapToList map[int]*Test
func MakeTest() (t List, mt MapToList) {
t = []*Test{}
mt = make(map[int]*Test)
var one, two, three string
one = "one"
two = "two"
three = "three"
t = append(t, &Test{1, &one})
mt[1] = t[len(t)-1]
t = append(t, &Test{2, &two})
mt[2] = t[len(t)-1]
t = append(t, &Test{3, &three})
mt[3] = t[len(t)-1]
return
}
func (s *List) Modify() {
for index := range *s {
var str string = "xxx"
(*s)[index].two = &str
}
}
func main() {
t, mt := MakeTest()
fmt.Println("Orginal")
for index := range t{
fmt.Println(index, t[index].one, *t[index].two)
}
t.Modify()
fmt.Println("Modified List")
for index := range t{
fmt.Println(index, t[index].one, *t[index].two)
}
fmt.Println("Modified Map")
for key, value := range mt {
fmt.Println(key, value.one, *value.two)
}
}
https://play.golang.org/p/KvG3Mj4v1u
输出为
Orginal
0 1 one
1 2 two
2 3 three
Modified List
0 1 xxx
1 2 xxx
2 3 xxx
Modified Map
1 1 xxx
2 2 xxx
3 3 xxx
我有一个或多或少复杂的结构的切片,我希望这个切片的所有元素都可以通过映射访问。该映射包含指向切片元素的指针。我现在的问题是,当我更改切片元素的内容时,它不会反映在指向该元素的映射中。 IE。如果我从切片访问更改的元素,我会看到更改。但是,如果我从地图访问该元素,则看不到更改。
我制作了一个抽象代码示例,您可以在下面找到它。在这里它变得更加奇怪,因为我看到一个元素发生了变化,尽管所有元素都应该改变。
package main
import "fmt"
type Test struct {
one int
two *string
}
type List []Test
type MapToList map[int]*Test
func MakeTest() (t List, mt MapToList) {
t = []Test{}
mt = make(map[int]*Test)
var one, two, three string
one = "one"
two = "two"
three = "three"
t = append(t, Test{1, &one})
mt[1] = &t[len(t)-1]
t = append(t, Test{2, &two})
mt[2] = &t[len(t)-1]
t = append(t, Test{3, &three})
mt[3] = &t[len(t)-1]
return
}
func (s *List) Modify() {
for index := range *s {
var str string = "xxx"
(*s)[index].two = &str
}
}
func main() {
t, mt := MakeTest()
fmt.Println("Orginal")
for index := range t{
fmt.Println(index, t[index].one, *t[index].two)
}
t.Modify()
fmt.Println("Modified List")
for index := range t{
fmt.Println(index, t[index].one, *t[index].two)
}
fmt.Println("Modified Map")
for key, value := range mt {
fmt.Println(key, value.one, *value.two)
}
}
输出为:
Orginal
0 1 one
1 2 two
2 3 three
Modified List
0 1 xxx
1 2 xxx
2 3 xxx
Modified Map
1 1 one
2 2 two
3 3 xxx
我会一直在切片和映射中使用指针。这简化了很多。
当您使用值切片时,碰巧 &t[i]
在 append
操作之后变成指向旧的废弃切片中的元素的指针。当您访问它时,您正在访问旧切片的元素。因此 map 正在引用旧切片的元素。
使用指针解决了这个问题,因为每个 Test
结构只有一个副本,并且有多个指向它们的指针。指针在旧切片、新切片或映射中并不重要。
package main
import "fmt"
type Test struct {
one int
two *string
}
type List []*Test
type MapToList map[int]*Test
func MakeTest() (t List, mt MapToList) {
t = []*Test{}
mt = make(map[int]*Test)
var one, two, three string
one = "one"
two = "two"
three = "three"
t = append(t, &Test{1, &one})
mt[1] = t[len(t)-1]
t = append(t, &Test{2, &two})
mt[2] = t[len(t)-1]
t = append(t, &Test{3, &three})
mt[3] = t[len(t)-1]
return
}
func (s *List) Modify() {
for index := range *s {
var str string = "xxx"
(*s)[index].two = &str
}
}
func main() {
t, mt := MakeTest()
fmt.Println("Orginal")
for index := range t{
fmt.Println(index, t[index].one, *t[index].two)
}
t.Modify()
fmt.Println("Modified List")
for index := range t{
fmt.Println(index, t[index].one, *t[index].two)
}
fmt.Println("Modified Map")
for key, value := range mt {
fmt.Println(key, value.one, *value.two)
}
}
https://play.golang.org/p/KvG3Mj4v1u
输出为
Orginal
0 1 one
1 2 two
2 3 three
Modified List
0 1 xxx
1 2 xxx
2 3 xxx
Modified Map
1 1 xxx
2 2 xxx
3 3 xxx