在Go JSON封送中嵌入map [string] string,无需额外的JSON属性(内联)

Is there a way to embed a map[string]string inline?

What I got is:

{
    "title": "hello world",
    "body": "this is a hello world post",
    "tags": {
        "hello": "world"
    }
}

What I mean with embed or inline would be an expected result like this:

    {
    "title": "hello world",
    "body": "this is a hello world post",
    "hello": "world"
}

This is my code... I load the information from a yaml file an want to return the JSON in the desired format from above:

This is my yaml:

title: hello world
body: this is a hello world post
tags:
  hello: world

This is my Go code:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"

    "gopkg.in/yaml.v2"
)

type Post struct {
    Title string            `yaml:"title" json:"title"`
    Body  string            `yaml:"body" json:"body"`
    Tags  map[string]string `yaml:"tags" json:",inline"`
}

func main() {

    yamlBytes, err := ioutil.ReadFile("config.yaml")
    if err != nil {
        panic(err)
    }

    var post Post

    yaml.Unmarshal(yamlBytes, &post)

    jsonBytes, err := json.Marshal(post)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(jsonBytes))

}

This obviously does work:

Tags map[string]string `yaml:"tags" json:",inline"`

but I was hoping that something similar exists to embed the tags map without the JSON property tags.

There is no native way to "flatten" fields, but you can do it manually with a series of Marshal/Unmarshal steps (error handling omitted for brevity):

type Post struct {
    Title string            `yaml:"title" json:"title"`
    Body  string            `yaml:"body" json:"body"`
    Tags  map[string]string `yaml:"tags" json:"-"` // handled by Post.MarshalJSON
}

func (p Post) MarshalJSON() ([]byte, error) {
    // Turn p into a map
    type Post_ Post // prevent recursion
    b, _ := json.Marshal(Post_(p))

    var m map[string]json.RawMessage
    _ = json.Unmarshal(b, &m)

    // Add tags to the map, possibly overriding struct fields
    for k, v := range p.Tags {
        // if overriding struct fields is not acceptable:
        // if _, ok := m[k]; ok { continue }
        b, _ = json.Marshal(v)
        m[k] = b
    }

    return json.Marshal(m)
}

https://play.golang.org/p/Xvu2VYeZFGh