如何在Go中获取结构类型?

时间:2019-01-15 11:47:52

标签: go

我正在研究一个演示项目,以了解GO语言。我定义了一个接口和2个struct类型。另外,我定义了一个接口数组。根据用户输入,我将数组中的每个元素定义为一种结构类型。在数据操作期间,我要检查数组上定义的结构的类型。

我尝试使用反射,但是不幸的是它没有用。另外,互联网上的其他方法也无效。我收到诸如panic或json的消息无法解组。

type Main_interface interface {
}

type Struct1 struct {
    Index                         int
    ID                            int
    Name                          string
}

type Struct2 struct {
    Index                         int
    Timestamp                     string
    Temporary_ID                  int
}


var MyArray []Main_interface

//...
NewStruct1Block := generateStruct1Block(...)
MyArray = append(MyArray, NewStruct1Block)

//...
NewStruct2Block := generateStruct2Block(...)
MyArray = append(MyArray, NewStruct2Block)

更新:我希望能够根据用户输入检查运行时实现接口的结构的类型。

2 个答案:

答案 0 :(得分:5)

您的数组可以是异构的,也就是说,它可以包含不同类型的元素。您不能确保(在编译时)所有元素都属于同一类型。

也就是说,您可以使用类型转换语法检查单个元素。

您有三个选择:

选项1:检查特定类型

var unknown Main_Interface = getSomethingSomewhere()
result, ok := unknown.(Struct1);
if ok {
    // result has type `Struct1` 
}

选项2:使用switch语句覆盖多种类型(已经在另一个答案中显示)

switch t := unknown.(type) {
case Struct1:
    // t has type `Struct1` within this block (at compile time)
case Struct2:
    // t has type `Struct2` within this block (at compile time)
default:
    // neither Struct1 no Struct2
}

选项3:在运行时与另一种类型进行比较。

请注意,reflect.TypeOf返回的类型可以使用==运算符进行比较,如下所示:

https://golang.org/pkg/reflect/#Type

  

类型值是可比较的,例如==运算符,因此它们可用作映射键。如果两个Type值表示相同的类型,则它们相等。

所以我们可以做这样的事情:

var s1 Struct1 // empty struct
var s2 Struct2 // empty struct
if reflect.TypeOf(unknown) == reflect.TypeOf(s1) {
    // unknown holds an s1 instance
}

但是当您只可以执行编译时检查时,这显然没有用。相反,您可以比较两个未知数以检查它们是否相同:

var unknown1 Main_Interface = getSomethingSomewhere()
var unknown2 Main_Interface = getSomethingSomewhereElse()

if reflect.TypeOf(unknown1) == reflect.TypeOf(unknown2) {
    // they are the same type
}

答案 1 :(得分:1)

您需要使用以下类型声明:

var MyArray []Main_interface

NewStruct1Block := Struct1{}
NewStruct2Block := Struct2{}

MyArray = append(MyArray, NewStruct1Block)
MyArray = append(MyArray, NewStruct2Block)

fmt.Printf("%v", MyArray)

switch t := MyArray[0].(type) {
case Struct1:
    fmt.Printf("%v", t)
    t.ID = 1
case Struct2:
    fmt.Printf("%v", t)
    t.Timestamp = "A"
default:
    fmt.Print("unknown")
}

此处的工作代码: https://play.golang.org/p/OhpBDJu_q2x