Это проще, если вы думаете только о данных ...
Ваш X должен быть не интерфейсом, а структурой, чтобы вы могли его маршалировать.
Чтобы сделать процесс общим, вы можете считать, что X содержит выбор
type A struct {
A int64
}
type B struct {
S string
}
type Choice int
const (
XisA Choice = iota
XisB
)
type X struct {
Choice
A
B
}
Перед маршалингом вам просто нужно установить выбор для каждого элемента вашего массива
a := A{
A: 1,
}
b := B{
S: "2",
}
x1 := X{
Choice: XisA,
A: a,
}
x2 := X{
Choice: XisB,
B: b,
}
x := [2]X{x1, x2}
После демаршаллинга вам просто нужно получить выбор, который вы сделали для каждого элемента массива
for _, item := range decoded {
switch {
case item.Choice == XisA:
println(item.A.GetKey())
case item.Choice == XisB:
println(item.B.GetKey())
}
}
Вот пример: https://play.golang.org/p/RtzF6DmNlKL