简体   繁体   中英

Check if underlying type is a struct with reflect

Given this struct

type A struct {
  b *B
  c string
  d string
}

I want to check with reflect which fields have a struct behind the pointer type, so specifically I want to create a condition that would only be true when iterating over field b . From what I've tried using the reflect documentation I always end up with an invalid Value kind which doesn't allow me to go further as every subsequent method panics.

package main

import (
    "fmt"
    "reflect"
)

type A struct {
  b *B
  c string
  d string
}

type B struct {
}

func main() {
        val := reflect.ValueOf(A{})
    for i := 0; i < val.Type().NumField(); i++ {
        if val.Field(i).Kind() == reflect.Ptr {
            fmt.Println(reflect.Indirect(val.Field(i)).Kind())
        }
        fmt.Println(val.Field(i).Kind())
    }
}

https://play.golang.org/p/oRry3ZubRxI

You get invalid value, because the val.b pointer field is nil , and you can't dereference a nil pointer. If you want your code to work, you have to initialize it with a valid pointer:

val := reflect.ValueOf(A{b: &B{}})

With this change it works and outputs (try it on the Go Playground ):

struct
ptr
string

If you want it to work without having to initialize the pointer, then you have to work on the types and not values :

val := reflect.ValueOf(A{})
t := val.Type()
for i := 0; i < t.NumField(); i++ {
    if ft := t.Field(i).Type; ft.Kind() == reflect.Ptr {
        fmt.Println(ft.Elem().Kind())
    }
    fmt.Println(t.Field(i).Type.Kind())
}

This outputs the same, try this one on the Go Playground .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM