go - 如何通过接口(interface)获取指针的值类型?

标签 go

playground说明了我的问题。

基本上我有一个接受空接口(interface)作为参数的函数。我想传入任何内容并打印有关类型和值的信息。

它按预期工作,除非我将指针传递给自定义类型(在我的示例中为基础结构类型)。我不完全确定此时反射模型的结构。由于函数签名在我调用 reflect.Indirect(v).Kind() 时指定了一个 interface{} 参数,因此它自然会返回 interface 但我想知道调用函数时的类型。

下面是来自 playground 的相同代码:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var s interface{}
    s = CustomStruct{}

    PrintReflectionInfo(s)
    PrintReflectionInfo(&s)
}

type CustomStruct struct {}

func PrintReflectionInfo(v interface{}) {
    // expect CustomStruct if non pointer
    fmt.Println("Actual type is:", reflect.TypeOf(v))

    // expect struct if non pointer
    fmt.Println("Value type is:", reflect.ValueOf(v).Kind())

    if reflect.ValueOf(v).Kind() == reflect.Ptr {
        // expect: CustomStruct
        fmt.Println("Indirect type is:", reflect.Indirect(reflect.ValueOf(v)).Kind()) // prints interface

        // expect: struct
        fmt.Println("Indirect value type is:", reflect.Indirect(reflect.ValueOf(v)).Kind()) // prints interface
    }

    fmt.Println("")
}

最佳答案

要获取结构值,需要获取接口(interface)值的element :

fmt.Println("Indirect type is:", reflect.Indirect(reflect.ValueOf(v)).Elem().Type()) // prints main.CustomStruct

fmt.Println("Indirect value type is:", reflect.Indirect(reflect.ValueOf(v)).Elem().Kind()) // prints struct

playground example

这段代码有助于理解示例中的类型:

rv := reflect.ValueOf(v)
for rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface {
    fmt.Println(rv.Kind(), rv.Type(), rv)
    rv = rv.Elem()
}
if rv.IsValid() {
    fmt.Println(rv.Kind(), rv.Type(), rv)
}

&s 的输出是:

ptr *interface {} 0xc000010200
interface interface {} {}
struct main.CustomStruct {}

playground example

关于go - 如何通过接口(interface)获取指针的值类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35110366/

相关文章:

go - 将所有错误处理的 golang 错误代码替换为 panic

go - 解码嵌套在列表中的 YAML 映射

docker - 在docker容器中进行CPU限制后如何运行Go程序?

go - 获取类似 python 的 split() 与 go 的 strings.Split() 一起工作

dictionary - 在 map 中存储值和 slice

go - 两个客户端在 Consul 中获取相同的锁

java - Golang 和大内存块分配

docker - Docker scratch 默认包含什么?

json - 如何正确解码 Golang 中的无键 JSON 数组?

go - 当消费者尝试连接到停机代理时,Sarama 库中会发生什么?