英文:
Creating a map from an array of struct pointers
问题
我有一个指向结构体的指针数组。这些结构体有一个name
字段。我想创建一个从名称到结构体指针的映射。
为什么registry
映射中的所有值都相同?
package main
import "fmt"
type Thing struct {
Name string
Value int
}
type Registry map[string]*Thing
func toRegistry(things []Thing) Registry {
registry := make(Registry)
for _, thing := range things {
registry[thing.Name] = &thing
}
return registry
}
func main() {
things := []Thing{{"thingA", 1}, {"thingB", 2}}
registry := toRegistry(things)
fmt.Println(registry)
}
输出示例:map[thingB:0x10436180 thingA:0x10436180]
根据@tvblah的建议,things
已经是一个切片,所以不需要对其进行指针引用。更新后的代码如下:
package main
import "fmt"
type Thing struct {
Name string
Value int
}
type Registry map[string]*Thing
func toRegistry(things []Thing) Registry {
registry := make(Registry)
for _, thing := range things {
registry[thing.Name] = &thing
}
return registry
}
func main() {
things := []Thing{{"thingA", 1}, {"thingB", 2}}
registry := toRegistry(things)
fmt.Println(registry)
}
[GO](https://play.golang.org/p/tbZt6WWyEd)
英文:
I have an array of pointers to structs. The structs have a name
field. I want to create a map from names to pointers to structs.
Why are all of the values in the registry
map identical?
package main
import "fmt"
type Thing struct {
Name string
Value int
}
type Registry map[string]*Thing
func toRegistry(things *[]Thing) Registry {
registry := make(Registry)
for _, thing := range *things {
registry[thing.Name] = &thing
}
return registry
}
func main() {
things := []Thing{{"thingA", 1}, {"thingB", 2}}
registry := toRegistry(&things)
fmt.Println(registry)
}
Sample output: map[thingB:0x10436180 thingA:0x10436180]
EDIT
Per @tvblah's suggestion, things
was already a slice, so there's no need to point to it:
package main
import "fmt"
type Thing struct {
Name string
Value int
}
type Registry map[string]*Thing
func toRegistry(things []Thing) Registry {
registry := make(Registry)
for _, thing := range things {
registry[thing.Name] = &thing
}
return registry
}
func main() {
things := []Thing{{"thingA", 1}, {"thingB", 2}}
registry := toRegistry(things)
fmt.Println(registry)
答案1
得分: 3
每个映射值都是指向单个局部变量thing
的指针。
一种修复方法是在切片元素中添加一个指针:
func toRegistry(things []Thing) Registry {
registry := make(Registry)
for i := range things {
registry[things[i].Name] = &things[i]
}
return registry
}
另一种选择是在切片中存储指向Thing
的指针:
func toRegistry(things []*Thing) Registry {
registry := make(Registry)
for _, thing := range things {
registry[thing.Name] = thing
}
return registry
}
func main() {
things := []*Thing{&Thing{"thingA", 1}, &Thing{"thingB", 2}}
registry := toRegistry(things)
fmt.Println(registry)
}
我将函数参数从指向切片的指针更改为切片。这个更改对于问题的解决没有影响,但这通常是Go代码的编写方式。在Go中很少使用指向切片的指针。
英文:
Each map value is a pointer to the single local variable thing
.
One fix is to add an pointer to the slice element:
func toRegistry(things []Thing) Registry {
registry := make(Registry)
for i := range things {
registry[things[i].Name] = &things[i]
}
return registry
}
Another option is to store pointers to Thing
in the slice:
func toRegistry(things []*Thing) Registry {
registry := make(Registry)
for _, thing := range things {
registry[thing.Name] = thing
}
return registry
}
func main() {
things := []*Thing{&Thing{"thingA", 1}, &Thing{"thingB", 2}}
registry := toRegistry(things)
fmt.Println(registry)
}
I changed the function argument from a pointer to a slice to a slice. This change has no impact on the issue raised on the question, but it's generally how Go code is written. Pointers to slices are rarely used in Go.
答案2
得分: 2
你可以在每次迭代中将thing
重新分配给另一个局部变量,并将新变量存储在注册表中。
package main
import "fmt"
type Thing struct {
Name string
Value int
}
type Registry map[string]*Thing
func toRegistry(things *[]Thing) Registry {
registry := make(Registry)
for _, thing := range *things {
t := thing
registry[thing.Name] = &t
}
return registry
}
func main() {
things := []Thing{{"thingA", 1}, {"thingB", 2}}
registry := toRegistry(&things)
fmt.Println(registry)
}
英文:
You may reassign thing
to another local variable on each iteration and store new variable in registry.
package main
import "fmt"
type Thing struct {
Name string
Value int
}
type Registry map[string]*Thing
func toRegistry(things *[]Thing) Registry {
registry := make(Registry)
for _, thing := range *things {
t := thing
registry[thing.Name] = &t
}
return registry
}
func main() {
things := []Thing{{"thingA", 1}, {"thingB", 2}}
registry := toRegistry(&things)
fmt.Println(registry)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论