从reflect.Value中提取uintptr

Given

// I know that behind SomeInterface can hide either int or a pointer to struct
// In the real code I only have v, not i
i := something.(SomeInterface)
v := reflect.ValueOf(i)
var p uintptr
if "i is a pointer to struct" {
    p = ???
}
  1. I need some way to distinguish between pointers and values in this situation.
  2. If i was a pointer to struct, I need to cast it to uintptr.

Something I discovered so far: the second member of the (*reflect.Value).InterfaceData() will be the pointer to the struct, in case it is a struct. I have no idea what it is in case it is not a struct.

Use the Pointer method to get the address of a struct as a uintpr:

var p uintptr
if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
    p = v.Pointer()
}

playground example

This code assumes that v is the result of calling reflect.ValueOf(i) as shown in the question. In this scenario, v represents i's element, not i. For example, if interface i contains an int, then v.Kind() is reflect.Int, not reflect.Interface.

If v has an interface value, then drill down through the interface to get the uintptr:

if v.Kind() == reflect.Interface {
    v = v.Elem()
}
var p uintptr
if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
    p = v.Pointer()
}

playground example