从结构指针数组创建映射
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)
每个映射值都是指向单个局部变量的指针 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 中很少使用指向切片的指针。
您可以在每次迭代时将 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)
}
我有一个结构指针数组。这些结构有一个 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)
每个映射值都是指向单个局部变量的指针 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 中很少使用指向切片的指针。
您可以在每次迭代时将 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)
}