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

如何在Go中获取结构类型?,go,Go,我正在做一个演示项目,以了解围棋语言。我定义了一个接口和两个结构类型。此外,我还定义了一系列接口。根据用户输入,我将数组中的每个元素定义为一种结构类型。在数据操作期间,我想检查数组上定义的结构的类型 我曾尝试使用reflect,但不幸的是,它不起作用。互联网上的其他方法也不起作用。我收到了诸如panic或json之类的消息,无法解组 type Main_interface interface { } type Struct1 struct { Index

我正在做一个演示项目,以了解围棋语言。我定义了一个接口和两个结构类型。此外,我还定义了一系列接口。根据用户输入,我将数组中的每个元素定义为一种结构类型。在数据操作期间,我想检查数组上定义的结构的类型

我曾尝试使用reflect,但不幸的是,它不起作用。互联网上的其他方法也不起作用。我收到了诸如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)

更新:我希望能够检查运行时实现接口的结构类型,具体取决于用户输入。

您需要使用类型资产,如下所示:

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")
}
此处的工作代码:

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

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

您有三种选择:

选项1:对照特定类型进行检查

var unknown Main_Interface = getSomethingSomewhere()
result, ok := unknown.(Struct1);
if ok {
    // result has type `Struct1` 
}
选项2:使用switch语句覆盖多种类型(已在另一个答案中给出)

选项3:在运行时与其他类型进行比较

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

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

所以我们可以这样做:

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
}

不清楚你遇到了什么错误,或者你到底想做什么。有关类型断言的基础知识,请参见此答案和本go教程部分-也许这就是您要寻找的?这里最好的建议可能是:不要尝试使用反射来理解发生了什么。反思是困难的。即使您知道该语言、接口和类型系统如何工作,也很难做到这一点。试图通过使用反射来提高您对类型系统的理解是注定要失败的。如果您尝试了某个方法,但它不起作用,请在问题主体中包含该代码,以及该方法不起作用的详细信息。我尝试了下面描述的两种解决方案。我主要通过硬编码初始化数组的第一个元素。该元件的型式试验效果良好。其余元素根据用户输入进行初始化,返回的元素类型为接口类型。我不要这个。我想要返回结构1或结构2。好的,您的问题的答案是
键入assestion
。在不了解您的特定需求的情况下,为您提供一个完全工作的应用程序(此资源不适用于此目的)是不可能的,因为当前这些需求看起来有点混乱。不幸的是,此解决方案返回的是Main_接口类型。我想返回Struct1类型或Struct2类型,即使我只追加Struct1或Struct1类型,你确定吗?此解决方案根本不返回类型,如果类型为
Struct1
Struct2
,则打印值,否则打印
unknown
。不打印。请检查游乐场中更新的代码:您可以将结构值分配给
t
。此解决方案仅适用于我主要通过硬编码初始化的数组的第一个元素。其余的元素作为主接口返回。为了清楚起见,选项1是一个类型断言,而不是类型转换:这些解决方案仅适用于我通过硬编码在main中初始化的数组的第一个元素。其余元素作为主界面返回。@Liviu如果这不能回答您的问题,那么我不理解您的问题。也许你能更清楚地解释一下?
var unknown1 Main_Interface = getSomethingSomewhere()
var unknown2 Main_Interface = getSomethingSomewhereElse()

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