【问题标题】:Extract uintptr from reflect.Value从 reflect.Value 中提取 uintptr
【发布时间】:2017-07-26 02:23:53
【问题描述】:

给定

// 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. 在这种情况下,我需要一些方法来区分指针和值。
  2. 如果i 是指向结构的指针,我需要将其转换为uintptr

到目前为止我发现的一些东西:(*reflect.Value).InterfaceData() 的第二个成员将是指向结构的指针,以防它是一个结构。如果它不是结构,我不知道它是什么。

【问题讨论】:

  • 任何东西都可以实现接口,甚至是intstring 或指向不是结构的结构的指针。
  • @kopiczko 你想说什么?
  • @wvxvw:你是在问如何检查 v 的 reflect.Kind 是否是一个指针?请注意,您无法将指针值正确存储在 uintptr
  • @wvxvw 我说过关于你的陈述:“如果它不是结构,我不知道它是什么。”
  • @kopiczko 好的,我知道现在的混乱来自哪里。我指的是InterfaceData() 返回的第二个值。我想你说的是不同的基本类型是否可以实现接口。

标签: pointers go interface casting


【解决方案1】:

使用Pointer方法获取结构体的地址作为uintpr:

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

playground example

此代码假定v 是调用reflect.ValueOf(i) 的结果,如问题所示。在这种情况下,v 代表i 的元素,而不是i。例如,如果接口i 包含int,则v.Kind()reflect.Int,而不是reflect.Interface

如果v有接口值,则通过接口向下钻取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

【讨论】:

  • 让我先检查一下,但从表面上看,在您的第二个清单中,如果接口后面的实际值不是指针(例如整数),v = v.Elem() 会恐慌。
  • v = v.Elem() 语句仅在v 为接口时执行。声明不会恐慌。
  • 请注意,接口上的v.Elem() 返回v 包含的值。如果接口包含整数,则v.Elem() 返回整数值。我更新了第二个示例以包含一个包含整数的接口。
猜你喜欢
  • 2021-01-21
  • 2018-06-14
  • 2013-08-08
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-21
相关资源
最近更新 更多