【发布时间】:2017-08-23 00:51:00
【问题描述】:
我想构建一个将结构作为interface{} 的方法,如果提供的结构的任何字段为零,则返回true。
这是我目前拥有的:
// ContainsNil returns true if any fields within the supplied structure are nil.
//
// If the supplied object is not a struct, the method will panic.
// Nested structs are inspected recursively.
// Maps and slices are not inspected deeply. This may change.
func ContainsNil(obj interface{}) bool {
if obj == nil {
return true
}
s := reflect.Indirect(reflect.ValueOf(obj))
for i := 0; i < s.NumField(); i++ {
f := s.Type().Field(i)
field := s.Field(i)
if fieldIsExported(f) { // Exported-check must be evaluated first to avoid panic.
if field.Kind() == reflect.Struct {
if ContainsNil(field.Addr()) {
return true
}
} else {
if field.IsNil() {
return true
}
if field.Interface() == nil {
return true
}
}
}
}
return false
}
func fieldIsExported(field reflect.StructField) bool {
log.Println(field.Name)
return field.Name[0] >= 65 == true && field.Name[0] <= 90 == true
}
还有一个失败的测试:
func Test_ContainsNil_NilNestedValue_ReturnsTrue(t *testing.T) {
someNestedStruct := &c.SomeNestedStruct{
SomeStruct: c.SomeStruct{
SomeString: nil,
},
}
result := util.ContainsNil(someNestedStruct)
assert.True(t, result)
}
测试代码在没有恐慌的情况下执行,但由于方法返回false而不是true而失败。
我遇到的问题是我无法弄清楚如何正确地将嵌套结构传递回对ContainsNil 的递归调用。
当对嵌套结构进行递归调用时,fieldIsExported 方法返回 false,因为它没有收到我期望它收到的值。
我希望fieldIsExported 在第一次调用时收到“SomeStruct”,并在第二次(递归)调用时收到“SomeString”。第一次通话按预期进行,但在第二次通话中,fieldIsExported 收到“typ”,而我希望它收到“SomeString”。
我已经做了很多关于在结构上使用反射的研究,但我还没有搞清楚这个问题。想法?
参考资料:
【问题讨论】:
标签: recursion go reflection