为了区分自定义类型和预定义类型,我们可以使用两种反射方法:
自定义类型将具有非空包路径和非空名称。相反,预定义类型将具有空包路径。
匿名结构类型:
匿名结构类型未命名,但可能有自定义类型的字段。我们可以通过迭代结构体的字段并检查其中是否有自定义类型来检查自定义类型。
映射类型:
映射类型可以具有自定义键或值类型。我们可以使用 Type.Elem() 查询值类型,使用 Type.Key() 查询键类型。
func isCustom(t reflect.Type) bool { if t.PkgPath() != "" { return true } if k := t.Kind(); k == reflect.Array || k == reflect.Chan || k == reflect.Map || k == reflect.Ptr || k == reflect.Slice { return isCustom(t.Elem()) || (k == reflect.Map && isCustom(t.Key())) } else if k == reflect.Struct { for i := t.NumField() - 1; i >= 0; i-- { if isCustom(t.Field(i).Type) { return true } } } return false }
fmt.Println(isCustom(reflect.TypeOf(""))) // false fmt.Println(isCustom(reflect.TypeOf(int(2)))) // false fmt.Println(isCustom(reflect.TypeOf([]int{}))) // false fmt.Println(isCustom(reflect.TypeOf(struct{ i int }{}))) // false fmt.Println(isCustom(reflect.TypeOf(&i))) // false fmt.Println(isCustom(reflect.TypeOf(map[string]int{}))) // false fmt.Println(isCustom(reflect.TypeOf(A{}))) // true fmt.Println(isCustom(reflect.TypeOf(&A{}))) // true fmt.Println(isCustom(reflect.TypeOf([]A{}))) // true fmt.Println(isCustom(reflect.TypeOf([][]A{}))) // true fmt.Println(isCustom(reflect.TypeOf(struct{ a A }{}))) // true fmt.Println(isCustom(reflect.TypeOf(map[K]int{}))) // true fmt.Println(isCustom(reflect.TypeOf(map[string]K{}))) // true
以上是我们如何使用 Go 反射区分自定义类型和内置类型?的详细内容。更多信息请关注PHP中文网其他相关文章!