JSON的编组和解组结构会丢失信息

I'm trying to marshal a struct into json (works as expected) and directly unmarshalling it again, but it seems as if information gets lost.

This is probably a design flaw in my application but as I'm a go beginner I don't know better. Help appreciated.

package main

import (
    "encoding/json"
    "fmt"
)

type Flow interface {
    Exec(input map[string]string) (output map[string]string, err error)
}

type FlowData struct {
    Static map[string]string
    Output map[string]string
}

type FooFlow struct {
    Data FlowData
}

func (flow FooFlow) Exec(input map[string]string) (output map[string]string, err error) {
    output = map[string]string{"message": flow.Data.Static["message"]}
    return output, nil
}

type BarFlow struct {
    Data FlowData
}

func (flow BarFlow) Exec(input map[string]string) (output map[string]string, err error) {
    output = map[string]string{"message": flow.Data.Static["prefix"] + "_bar"}
    return output, nil
}

type Pipeline struct {
    Entrypoint string
    Flows      map[string]Flow
}

func main() {
    foo := FooFlow{
        Data: FlowData{
            Static: map[string]string{"message": "foo"},
        },
    }

    bar := BarFlow{
        Data: FlowData{
            Static: map[string]string{"prefix:": "baz"},
        },
    }

    pipe := Pipeline{
        Entrypoint: "foobar",
        Flows: map[string]Flow{
            "foo": foo,
            "bar": bar,
        },
    }

    data, _ := json.Marshal(pipe)
    fmt.Printf("pipe1: %+v
", pipe)
    fmt.Println("json:", string(data))

    var pipe2 Pipeline
    json.Unmarshal(data, &pipe2)
    fmt.Printf("pipe2: %+v
", pipe2)
}

Executing this gives the following result:

pipe1: {Entrypoint:foobar Flows:map[foo:{Data:{Static:map[message:foo] Output:map[]}} bar:{Data:{Static:map[prefix::baz] Output:map[]}}]}

json: {"Entrypoint":"foobar","Flows":{"bar":{"Data":{"Static":{"prefix:":"baz"},"Output":null}},"foo":{"Data":{"Static":{"message":"foo"},"Output":null}}}}

pipe2: {Entrypoint:foobar Flows:map[bar:<nil> foo:<nil>]}

Apparently all information gets correctly marshalled into json. But the unmarshalling ignores the actual values of the Flows as just adds them to the map as <nil>.

How to properly solve this?

When a struct field is of an interface type, encoding/json has no way to know what concrete type to use to unmarshal into it, so it skips it. Either use a concrete type in the definition, or prepopulate the interface field(s) with empty concrete instances that it can unmarshal into.