Skip to content

Instantly share code, notes, and snippets.

@allanruin
Created February 8, 2014 07:23
Show Gist options
  • Save allanruin/8877939 to your computer and use it in GitHub Desktop.
Save allanruin/8877939 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
Weight float64
}
func main() {
p := new(Person)
p2 := &Person{"allan", 18, 62.3}
p3 := &Person{"", 0, 0.0}
TryIsValid(p)
TryIsValid(p2)
TryIsValid(p3)
TryIsZero(p)
TryIsZero(p2)
TryIsZero(p3)
// s := ""
// fmt.Println(IsZero(s))
}
// 看到文档说“IsValid returns true if v represents a value. It returns false
// if v is the zero Value.”
// 同时可以看到函数reflect.Zero(typ Type)返回的是是Type类型的零值。按我的理解
// 这种为(广义)“零值”的应该就是属于Zero了,所以IsValid应该返回 false才对。
// 实际上,及时对于一个未曾初始化的结构体里的field, IsValid返回的还是true
// SO上的这个问题问到了相似的情形:
// http://stackoverflow.com/questions/13901819/quick-way-to-detect-empty-values-via-reflection-in-go
func TryIsValid(p *Person) {
v := reflect.ValueOf(p)
ind := reflect.Indirect(v)
num := ind.NumField()
fmt.Println("****************************")
for i := 0; i < num; i++ {
fv := ind.Field(i)
if fv.IsValid() {
fmt.Println("Valid:", fv)
} else {
fmt.Println("Not a valid field value: ", fv)
}
}
fmt.Println("****************************\n")
}
func TryIsZero(p *Person) {
v := reflect.ValueOf(p)
ind := reflect.Indirect(v)
num := ind.NumField()
fmt.Println("****************************")
for i := 0; i < num; i++ {
fv := ind.Field(i)
if IsZero(fv) {
fmt.Println("Zero:", fv)
} else {
fmt.Println("Not Zero: ", fv)
}
}
fmt.Println("****************************\n")
}
func IsZero(v reflect.Value) bool {
return v == reflect.Zero(v.Type())
// return v == reflect.Zero(reflect.TypeOf(v)).Interface()
// 我感觉到了陷阱...
// 这里IsZero传入的如果是一个reflect.Value, TypeOf 一个Value会返回什么。。
//
}
@allanruin
Copy link
Author

这里显然不行了,reflect.Value是一个结构体,结构体与结构体比较,跟简单类型不一样,不能直接"=="的。但如果直接接受interface{},同样不能处理参数是Value的情形。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment