Loops 迭代Golang中的结构并打印值(如果已设置)
首先,如果这个问题被搞糊涂了,我要道歉,因为我只是尝试着去做,不知道我在做什么。我有一个由不同类型的各种属性组成的结构,例如:Loops 迭代Golang中的结构并打印值(如果已设置),loops,go,struct,Loops,Go,Struct,首先,如果这个问题被搞糊涂了,我要道歉,因为我只是尝试着去做,不知道我在做什么。我有一个由不同类型的各种属性组成的结构,例如: type foo struct { bar string baz int bez []string (...) 最初,我想迭代所有这些属性并打印值(如果存在),但我意识到不能像列表或映射那样对结构进行range。因此,我尝试了一些运气不佳的技巧(比如尝试迭代一个单独的属性列表),我认为我最好只是寻求帮助,因为我可能在这里超过了我的头脑 其想法是
type foo struct {
bar string
baz int
bez []string
(...)
最初,我想迭代所有这些属性并打印值(如果存在),但我意识到不能像列表或映射那样对结构进行range
。因此,我尝试了一些运气不佳的技巧(比如尝试迭代一个单独的属性列表),我认为我最好只是寻求帮助,因为我可能在这里超过了我的头脑
其想法是,如果我创建此结构的新实例,我希望能够只打印设置的值:
obj := foo{"bar_string", 1}
鉴于字符串切片bez
未在obj
中设置,我希望能够执行类似(伪)的操作:
给予:
"bar_string"
1
理想情况下,不打印[]
,我猜这是bez
的零值
我对这整件事的看法是错的吗?我不使用映射的原因是,我希望属性是不同的类型,并且为了清晰起见,我希望将来使用的不同对象被组织到结构中。Go没有内置的结构迭代。用于。。。范围语句仅适用于: 数组、切片、字符串或映射的所有条目,或在通道上接收的值 或使用这些基础类型之一定义的类型(例如,
类型Foo[]int
)
如果您想在编译时遍历已知的结构,最好只逐个访问字段
如果您想迭代编译时未知的结构,可以使用reflect
包(不推荐):
您可能应该使用reflect,但在struct属性上迭代这是一个非常好的主意。如果您希望有一个不同值类型的对象,并且只打印设置的值,您是否有一个不太奇怪的建议?我的印象是,例如,映射需要有一个单一的类型@pzkpfw这看起来很像您试图让go按照其他(非编译)语言习惯的方式运行。不要那样做。学习如何按照应该使用的方式使用语言。Go是一种静态类型语言,如果不使用类型反射和转换,就不能有空值或不同数据类型的映射。“其思想是,如果我创建此结构的新实例,我希望能够只打印设置的值”,这不是Go的工作方式。根本没有“unset”结构字段。如果不“设置”它们,编译器/运行时只会将它们设置为零值,而您(真的!)无法区分是设置值还是编译器。
"bar_string"
1
type Foo struct {
Bar string
Baz int
Quux []int
}
// x := Foo{"bar", 1, nil}
func printAny(x interface{}) {
v := reflect.ValueOf(x)
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
if !reflect.DeepEqual(field.Interface(), reflect.Zero(field.Type()).Interface()) {
fmt.Println(field)
// bar
// 1
}
}
}
type Foo struct {
Bar string
Baz int
Quux []int
}
func (f Foo) String() string {
s := []string{f.Bar, strconv.Itoa(f.Baz)}
if f.Quux != nil {
s = append(s, fmt.Sprintf("%v", f.Quux))
}
return strings.Join(s, "\n")
}
func main() {
fmt.Println(Foo{"bar", 1, nil})
// bar
// 1
}