How can I tell if my interface{} is a pointer?

huangapple go评论91阅读模式
英文:

How can I tell if my interface{} is a pointer?

问题

如果我将一个接口传递给一个函数,有没有办法判断传入的项是一个结构体还是一个指向结构体的指针?我写了这个简单的测试来说明我需要解决的问题。

type MyStruct struct {
    Value string
}

func TestInterfaceIsOrIsntPointer(t *testing.T) {
    var myStruct interface{} = MyStruct{Value: "hello1"}
    var myPointerToStruct interface{} = &MyStruct{Value: "hello1"}
    // 接口上没有IsPointer方法,但我需要类似这样的方法
    if myStruct.IsPointer() || !myPointerToStruct.IsPointer() {
        t.Fatal("期望myStruct不是指针,而myPointerToStruct是指针")
    }
}
英文:

If I have an interface being passed into a function, is there a way to tell if the item passed in is a struct or a pointer to a struct? I wrote this silly test to illustrate what I need to figure out.

type MyStruct struct {
	Value string
}

func TestInterfaceIsOrIsntPointer(t *testing.T) {
    var myStruct interface{} = MyStruct{Value: "hello1"}
	var myPointerToStruct interface{} = &MyStruct{Value: "hello1"}
    // the IsPointer method doesn't exist on interface, but I need something like this
    if myStruct.IsPointer() || !myPointerToStruct.IsPointer() { 
	    t.Fatal("expected myStruct to not be pointer and myPointerToStruct to be a pointer")
	}
}

答案1

得分: 12

func isStruct(i interface{}) bool {
return reflect.ValueOf(i).Type().Kind() == reflect.Struct
}

你可以根据需要进行测试,例如更改类型为reflect.Ptr。在确保它是指针后,你甚至可以使用reflect.Indirect(reflect.ValueOf(i))获取指向的值。

补充:

看起来reflect.Value有一个Kind方法,所以reflect.ValueOf(i).Kind()就足够了。

英文:
func isStruct(i interface{}) bool {
    return reflect.ValueOf(i).Type().Kind() == reflect.Struct
}

You can test via changing type according to your needs such as reflect.Ptr. You can even get pointed value with reflect.Indirect(reflect.ValueOf(i)) after you ensured it's a pointer.

Addition:

It seems reflect.Value has a Kind method so reflect.ValueOf(i).Kind() is enough.

答案2

得分: 3

你可以使用reflect包:

import (
	"fmt"
	"reflect"
)

func main() {
	i := 42
	j := &i
	kindOfJ := reflect.ValueOf(j).Kind()

	fmt.Print(kindOfJ == reflect.Ptr)
}

你可以使用reflect包来获取变量的类型信息。在上面的代码中,我们定义了一个整数变量i,然后使用&操作符获取了i的地址,并将其赋值给j。接下来,我们使用reflect.ValueOf()函数获取j的值的类型,并使用Kind()方法获取类型的种类。最后,我们将kindOfJreflect.Ptr进行比较,以确定j是否为指针类型。

英文:

You could use the reflect package:

i := 42
j := &i
kindOfJ := reflect.ValueOf(j).Kind()

fmt.Print(kindOfJ == reflect.Ptr)

答案3

得分: 2

如果你知道接口的“真实”类型,你可以简单地使用type switch

type MyStruct struct {
    Value string
}

func TestInterfaceIsOrIsntPointer(t *testing.T) {
    var myStruct interface{} = MyStruct{Value: "hello1"}
    var myPointerToStruct interface{} = &MyStruct{Value: "hello1"}
    // 接口上没有IsPointer方法,但我需要类似这样的方法
    switch myStruct.(type) {
       case MyStruct:
           // 正常
           break
       case *MyStruct:
           // 这里有错误
           break
    }
    switch myPointerToStruct.(type) {
       case MyStruct:
           // 这里有错误
           break
       case *MyStruct:
           // 正常
           break
    }
}

这段代码更长,但至少你不需要使用reflect包。

英文:

If you know the "real" type of the interface, you can simply use a type switch:

type MyStruct struct {
    Value string
}

func TestInterfaceIsOrIsntPointer(t *testing.T) {
    var myStruct interface{} = MyStruct{Value: "hello1"}
    var myPointerToStruct interface{} = &MyStruct{Value: "hello1"}
    // the IsPointer method doesn't exist on interface, but I need something like this
    switch myStruct.(type) {
       case MyStruct:
           // ok
           break
       case *MyStruct:
           // error here
           break
    }
    switch myPointerToStruct.(type) {
       case MyStruct:
           // error here
           break
       case *MyStruct:
           // ok
           break
    }
}

The code is longer but at least you don't need to use the reflect package.

huangapple
  • 本文由 发表于 2015年7月8日 14:54:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/31285493.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定