如何在Go中获取结构类型? [关闭]

I am working on a demo project to understand GO language. I have defined one interface and 2 struct type. Also, I have defined an array of interfaces. Depending on the user input, I define each element within the array as a type of struct. During the data manipulation, I want to check the type of the struct defined on the array.

I have tried to use reflect, but unfortunately it did not worked. Also other methods on internet did not worked. I received messages such as panic or json cannot Unmarshal.

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)

UPDATE: I want to be able to check the kind of struct implements the interface at runtime, depending on the user input.

You need to use type assestion as below:

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")
}

Working code here: https://play.golang.org/p/OhpBDJu_q2x

Your array can be heteregenious, that is, it can contain elements of different types. You can't ensure (at compile time) that all elements are of the same type.

That said, you can check a single element using the type cast syntax.

You have three options:

Option 1: Check against a specific type

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

Option 2: Use a switch statement to cover multiple types (already presented in another answer)

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
}

Option 3: compare against another type at runtime.

Note that types returned by reflect.TypeOf are comparable using the == operator, as documented here:

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

Type values are comparable, such as with the == operator, so they can be used as map keys. Two Type values are equal if they represent identical types.

So we can do something like this:

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

But this is obviously not useful when you can just do the compile time check. Instead, you can compare two unknowns to check if they are the same:

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

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