我是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[:], " / ")
}