Home >Backend Development >Golang >How Can We Distinguish Custom Types from Built-in Types Using Go Reflection?

How Can We Distinguish Custom Types from Built-in Types Using Go Reflection?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2025-01-05 03:09:39778browse

How Can We Distinguish Custom Types from Built-in Types Using Go Reflection?

Identifying Non-Builtin Types Using Reflection

Identifying Custom Types

To differentiate between custom types and predefined types, we can utilize two reflection methods:

  • Type.PkgPath(): Returns the package path of a named type. Predefined types have an empty package path.
  • Type.Name(): Returns the name of a named type. Unnamed types return an empty string.

Custom types will have a non-empty package path and a non-empty name. Conversely, predefined types will have an empty package path.

Handling Special Cases

Anonymous Struct Types:

Anonymous struct types are unnamed but may have fields of custom types. We can check for custom types by iterating over the struct's fields and checking if any of them are custom.

Map Types:

Map types can have custom key or value types. We can query the value type using Type.Elem() and the key type using Type.Key().

Implementation Example

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
}

Testing

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

The above is the detailed content of How Can We Distinguish Custom Types from Built-in Types Using Go Reflection?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn