【发布时间】:2020-03-05 11:48:26
【问题描述】:
我有几个正在接收数据的结构。所有结构都应包含一些相同的数据,这些数据已嵌入HeaderData 结构中。数据不是同时填充的,我需要一个函数来检查是否所有的字段都收到了一个值(不是空字符串)。
我试图用反射解决这个问题。问题是反射会将HeaderData 视为一个字段。这意味着它将始终是一个非空字符串,尽管它可能包含空字段。所以我相信我需要一种方法来单独检查该结构。
我尝试使用 anyStruct.HeaderData 访问它,但这不起作用,因为“{} 是没有方法的接口”。
还有其他方法可以访问HeaderData 以使其有效吗?
或者我能否以某种方式在dataReady 中指定输入必须包含HeaderData 字段?
package main
import (
"fmt"
"reflect"
)
type HeaderData struct {
Param1 string
Param2 string
}
type Data1 struct {
HeaderData
Param3 string
Param4 string
}
type Data2 struct {
HeaderData
Param3 string
Param5 string
}
func dataReady(anyStruct interface{}) bool {
v := reflect.ValueOf(anyStruct)
for i := 0; i < v.NumField(); i++ {
// fmt.Println(v.Field(i).Interface())
if v.Field(i).Interface() == "" {
return false
}
}
// v1 := reflect.ValueOf(anyStruct.HeaderData)
// Not working:
// anyStruct.HeaderData undefined (type interface {} is interface with no methods)
return true
}
func main() {
d1 := Data1{HeaderData: HeaderData{Param1: "ABC", Param2: "DEF"}, Param3: "GHI", Param4: "JKL"}
d2 := Data2{HeaderData: HeaderData{Param1: "ABC", Param2: "DEF"}}
d3 := Data2{HeaderData: HeaderData{Param1: "ABC"}, Param3: "GHI", Param5: "JKL"}
d4 := Data2{Param3: "GHI", Param5: "JKL"}
fmt.Println("d1Ready: ", dataReady(d1)) //Returns true, which is correct
fmt.Println("d2Ready: ", dataReady(d2)) //Returns false, which is correct
fmt.Println("d3Ready: ", dataReady(d3)) //Returns true but should return false
fmt.Println("d4Ready: ", dataReady(d4)) //Returns true but should return false
}
【问题讨论】:
-
您为什么需要对此进行反思?有一个方法/函数来检查
HeaderData的字段和那些DataN结构的方法/函数;后者的方法/函数将调用方法/函数,该方法/函数将检查其中的 HeaderData field 的字段(它嵌入的事实并不排除通过其类型的名称访问它)。 -
您可能认为这是“代码过多”,但作为交换,它更易于理解(而且速度更快)。
-
@kostix 这是一个选项,也许我应该这样做。但是正如您提到的那样,它将需要更多代码,每个结构我都需要一个函数。此外,如果结构发生变化,我将不得不更新函数。所以我认为如果我有一种更通用的检查方式会很好。
标签: go struct reflection embedding go-reflect