Golang中如何访问结构体的字段
Golang中如何访问结构体的字段 假设我有一个结构体
type heights struct {
name string
height int // 以英寸为单位
}
假设我有4个实例,其中"Jim"是72英寸,"Mary"是61英寸,"Alex"是69英寸,"Ann"是58英寸。
我如何执行两个查询:
- 谁的身高是61英寸?
- Ann的身高是多少?
这似乎在我看过的所有教程中都没有解释。
@Yamil_Bracho 提出的方法可行,但根据你的需求,可能需要更复杂的处理。
例如,如果列表中的条目数量巨大,遍历整个切片可能会导致性能问题。在这种情况下,你需要使用更复杂的数据结构,比如映射(map)。
所提供的解决方案的另一个问题是,如果存在多个高度相同的条目,它将无法正常工作。
一个稍好一点的方案可能是:
func indexes(persons []Person, fn func(p Person) bool) []int {
results := make([]int, 0)
for i, p := range persons {
if fn(p) {
results = append(results, i)
}
}
return results
}
更多关于Golang中如何访问结构体的字段的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
更好的做法是将这些“对象”放入一个切片中,然后在该切片中进行搜索。例如
package main
import "fmt"
type Person struct {
name string
height int // 以英寸为单位
}
func index(persons []Person, fn func(p Person) bool) int {
for i, p := range persons {
if fn(p) {
return i
}
}
return -1
}
func main() {
persons := []Person{
Person{name: "Jim", height: 72},
Person{name: "Mary", height: 61},
Person{name: "Alex", height: 69},
Person{name: "Ann", height: 58},
}
// 谁的身高是61英寸
pos := index(persons, func(p Person) bool {
return p.height == 61
})
if pos != -1 {
fmt.Println(persons[pos])
} else {
fmt.Println("没有人身高61英寸")
}
// Ann的身高是多少
pos = index(persons, func(p Person) bool {
return p.name == "Ann"
})
if pos != -1 {
fmt.Println(persons[pos])
} else {
fmt.Println("Ann未注册")
}
}
也许你可以使用一个专门用于集合的包:
GitHub - sxyazi/go-collection at golangexample.com
基于泛型类型的、有用的 Go 语言集合函数 - GitHub - sxyazi/go-collection at golangexample.com
GitHub - marstr/collection: 几个基本数据结构的通用 Go 语言实现
几个基本数据结构的通用 Go 语言实现。 - GitHub - marstr/collection: 几个基本数据结构的通用 Go 语言实现。
GitHub - golang-collections/collections
通过在 GitHub 上创建账户来为 golang-collections/collections 的开发做出贡献。
在Go语言中,访问结构体字段主要有两种方式:直接使用字段名访问,或通过反射机制动态访问。以下是针对你问题的具体实现:
1. 直接字段访问(最常见的方式)
package main
import "fmt"
type Person struct {
name string
height int // 以英寸为单位
}
func main() {
// 创建实例
people := []Person{
{"Jim", 72},
{"Mary", 61},
{"Alex", 69},
{"Ann", 58},
}
// 查询1: 谁的身高是61英寸?
fmt.Println("身高61英寸的人:")
for _, p := range people {
if p.height == 61 { // 直接访问height字段
fmt.Println(p.name) // 直接访问name字段
}
}
// 查询2: Ann的身高是多少?
fmt.Println("\nAnn的身高:")
for _, p := range people {
if p.name == "Ann" { // 直接访问name字段
fmt.Printf("%d英寸\n", p.height) // 直接访问height字段
}
}
}
2. 使用map优化查询(适合频繁查询的场景)
package main
import "fmt"
type Person struct {
name string
height int
}
func main() {
// 创建map以便快速查询
peopleMap := map[string]Person{
"Jim": {"Jim", 72},
"Mary": {"Mary", 61},
"Alex": {"Alex", 69},
"Ann": {"Ann", 58},
}
// 查询1: 谁的身高是61英寸?
fmt.Println("身高61英寸的人:")
for name, p := range peopleMap {
if p.height == 61 {
fmt.Println(name)
}
}
// 查询2: Ann的身高是多少?
fmt.Println("\nAnn的身高:")
if ann, exists := peopleMap["Ann"]; exists {
fmt.Printf("%d英寸\n", ann.height)
}
}
3. 使用反射动态访问字段(当字段名不确定时)
package main
import (
"fmt"
"reflect"
)
type Person struct {
name string
height int
}
func main() {
people := []Person{
{"Jim", 72},
{"Mary", 61},
{"Alex", 69},
{"Ann", 58},
}
// 查询1: 使用反射查找身高61英寸的人
fmt.Println("身高61英寸的人:")
for _, p := range people {
v := reflect.ValueOf(p)
height := v.FieldByName("height").Int()
if height == 61 {
name := v.FieldByName("name").String()
fmt.Println(name)
}
}
// 查询2: 使用反射获取Ann的身高
fmt.Println("\nAnn的身高:")
for _, p := range people {
v := reflect.ValueOf(p)
name := v.FieldByName("name").String()
if name == "Ann" {
height := v.FieldByName("height").Int()
fmt.Printf("%d英寸\n", height)
}
}
}
4. 封装查询方法(推荐的生产环境做法)
package main
import "fmt"
type Person struct {
name string
height int
}
type People []Person
// 根据身高查找人名
func (p People) FindByHeight(targetHeight int) []string {
var result []string
for _, person := range p {
if person.height == targetHeight {
result = append(result, person.name)
}
}
return result
}
// 根据人名查找身高
func (p People) FindHeightByName(targetName string) (int, bool) {
for _, person := range p {
if person.name == targetName {
return person.height, true
}
}
return 0, false
}
func main() {
people := People{
{"Jim", 72},
{"Mary", 61},
{"Alex", 69},
{"Ann", 58},
}
// 查询1: 谁的身高是61英寸?
fmt.Println("身高61英寸的人:")
if names := people.FindByHeight(61); len(names) > 0 {
for _, name := range names {
fmt.Println(name)
}
}
// 查询2: Ann的身高是多少?
fmt.Println("\nAnn的身高:")
if height, found := people.FindHeightByName("Ann"); found {
fmt.Printf("%d英寸\n", height)
}
}
直接字段访问(第一种方法)是最常用和最高效的方式,通过结构体实例.字段名的语法即可访问。对于你的具体问题,第一个查询需要遍历比较height字段,第二个查询需要遍历比较name字段后获取对应的height字段值。

