获取Go中空结构切片的字段

huangapple go评论85阅读模式
英文:

Get fields of empty struct slice in Go

问题

我有一个函数:

func (r *render) foo(v interface{}) {
    val := reflect.ValueOf(v)
    fields := structs.Fields(val.Index(0).Interface())

    ...
}

该函数接受一个结构体切片,并尝试获取v的字段,但是如果v为空,则"val.Index(0)"会导致程序崩溃。有没有更好的方法来解决这个问题?

英文:

I have a function

func (r *render) foo(v interface{}) {
    val := reflect.ValueOf(v)
    fields := structs.Fields(val.Index(0).Interface())

...

Which takes a slice of structs and tries to get the fields of v,
however if v is empty then "val.Index(0)" crashes the program. Is there a better way to do this?

答案1

得分: 2

你需要首先检查是否有一个切片,然后检查是否有一个空切片,同时你可能也应该检查是否有一个结构体:(示例)

val := reflect.ValueOf(v)
if val.Kind() != reflect.Slice {
	fmt.Println("不是一个切片")
	return
}

if val.Len() == 0 {
	fmt.Println("空切片")
	return
}

if val.Index(0).Kind() != reflect.Struct {
	fmt.Println("不是一个结构体切片")
	return
}

fields := structs.Fields(val.Index(0).Interface())
...

如果你只想从结构体类型中获取字段,而不管切片是否为空,你可以使用切片类型的Elem方法来提取它(示例)

// 获取切片的内部类型
t := val.Type().Elem()
if t.Kind() != reflect.Struct {
	fmt.Println("不是一个结构体")
    return
}

fmt.Println("类型:", t)
for i := 0; i < t.NumField(); i++ {
	fmt.Println(t.Field(i).Name)
}
英文:

You need to check first if you have a slice to begin with, then check if you have an empty slice, and you probably should check that you have a struct too while you're at it: (example)

val := reflect.ValueOf(v)
if val.Kind() != reflect.Slice {
	fmt.Println(&quot;not a slice&quot;)
	return
}

if val.Len() == 0 {
	fmt.Println(&quot;empty slice&quot;)
	return
}

if val.Index(0).Kind() != reflect.Struct {
	fmt.Println(&quot;not a slice of structs&quot;)
	return
}

fields := structs.Fields(val.Index(0).Interface())
...

If you only want the fields from a struct type, regardless of if the slice is empty, you can use the slice type's Elem method to extract it (example)

// get the internal type of the slice
t := val.Type().Elem()
if t.Kind() != reflect.Struct {
	fmt.Println(&quot;not a struct&quot;)
    return
}

fmt.Println(&quot;Type:&quot;, t)
for i := 0; i &lt; t.NumField(); i++ {
	fmt.Println(t.Field(i).Name)
}

huangapple
  • 本文由 发表于 2015年8月11日 00:03:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/31924199.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定