带有接收器的函数,该函数在go中遍历结构的某个字段



我是Golang新手,正在尝试构建一个简单的CLI。我正在将API调用负载转换为一个结构,并希望将该结构中的一些信息格式化为一个漂亮的可打印字符串。我想打印的信息之一是来自一个结构数组,比如这个例子:

type Pokemon struct {
Abilities []struct {
Ability struct {
Name string `json:"name"`
URL  string `json:"url"`
} `json:"ability"`
IsHidden bool `json:"is_hidden"`
Slot     int  `json:"slot"`
} `json:"abilities"`
Height int    `json:"height"`
ID     int    `json:"id"`
Name   string `json:"name"`
Types  []struct {
Slot int `json:"slot"`
Type struct {
Name string `json:"name"`
URL  string `json:"url"`
} `json:"type"`
} `json:"types"`
Weight int `json:"weight"`
}
}

我正在尝试编写一个通用的受体函数,它迭代一些作为结构数组的字段,并将其字段连接到字符串中。我可以做一个函数,专门在一些字段上迭代,如下所示:

func (p Pokemon) stringifyPokemonAbilities() string {
var listOfAbilities []string
for _, ability := range p.Abilities {
listOfAbilities = append(listOfAbilities, ability.Ability.Name)
}
return strings.Join(listOfAbilities[:], " / ")
}

返回,例如synchronize / inner-focus

这样工作,我将不得不向Type字段写入几乎相同的函数。我的问题是,如何使这个函数更通用,接受一个字段并对其进行迭代。有什么想法吗?

您可以使用relfect来完成此操作。有一个写得很好的教程,你可以看看。

根据你给出的结构,我已经写了一个演示。主要思想是按名称查找结构文件,然后迭代器切片,在结构中查找名称。

您现在可以使用p.stringifyPokemon("Types")p.stringifyPokemon("Abilities")来获得答案。

func (p Pokemon) stringifyPokemon(field string) string {
value := reflect.ValueOf(p)
struct1 := value.FieldByName(field)
if !struct1.IsValid() {
return ""
}
if struct1.Type().Kind() != reflect.Slice {
return ""
}
ans := make([]string, 0)
for i := 0; i < struct1.Len(); i++ {
slice1 := struct1.Index(i)
if slice1.Type().Kind() != reflect.Struct {
continue
}
for j := 0; j < slice1.NumField(); j++ {
struct2 := slice1.Field(j)
if struct2.Type().Kind() != reflect.Struct {
continue
}
name := struct2.FieldByName("Name")
if name.Kind() != reflect.String {
continue
}
ans = append(ans, name.String())
}
}
return strings.Join(ans[:], " / ")
}

最新更新