将结构编码为json Go

I have an issue encoding struct to json my code is

type MainStructure struct {
    Text  string      json:"text,omitempty"
    Array []TestArray json:"test_array,omitmepty"
}

type TestArray struct { ArrayText string json:"array_text,omitempty" }

func main() { Test := MainStructure{ Text: "test", Array: [ { ArrayText: "test1" }, { ArrayText: "test2" } ] } body := new(bytes.Buffer) json.NewEncoder(body).Encode(&Test) fmt.Println(string([]byte(body))) }

the wanted result should be

{
    "text": "test",
    "test_array": [
        {
            "array_text": "test1"
        },
        {
            "array_text": "test2"
        }
    ]
}

I do not mind if it's "Marshal" or "encoding/json"

To encode a struct to JSON string, there are three ways that provided by standard library :

  • Using Encoder which convert struct to JSON string, then write it to io.Writer. This one usually used if you want to send JSON data as HTTP request, or saving the JSON string to a file.
  • Using Marshal which simply convert struct to bytes, which can be easily converted to string.
  • Using MarshalIndent which works like Marshal, except it's also prettify the output. This is what you want for your problem right now.

To compare between those three methods, you can use this code (Go Playground):

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
)

type MainStructure struct {
    Text  string      `json:"text,omitempty"`
    Array []TestArray `json:"test_array,omitempty"`
}

type TestArray struct {
    ArrayText string `json:"array_text,omitempty"`
}

func main() {
    Test := MainStructure{
        Text: "test",
        Array: []TestArray{
            {ArrayText: "test1"},
            {ArrayText: "test2"},
        },
    }

    // Using marshal indent
    btResult, _ := json.MarshalIndent(&Test, "", "  ")
    fmt.Println("Using Marshal Indent:
" + string(btResult))

    // Using marshal
    btResult, _ = json.Marshal(&Test)
    fmt.Println("
Using Marshal:
" + string(btResult))

    // Using encoder
    var buffer bytes.Buffer
    json.NewEncoder(&buffer).Encode(&Test)
    fmt.Println("
Using Encoder:
" + buffer.String())
}

The output will look like this :

Using Marshal Indent:
{
  "text": "test",
  "test_array": [
    {
      "array_text": "test1"
    },
    {
      "array_text": "test2"
    }
  ]
}

Using Marshal:
{"text":"test","test_array":[{"array_text":"test1"},{"array_text":"test2"}]}

Using Encoder:
{"text":"test","test_array":[{"array_text":"test1"},{"array_text":"test2"}]}

First of all I think you are going wrong on how to create a struct in go, as you can easily convert them to json.

You should be first making a proper struct then do json.marshal(Test) to convert it to proper json like:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {

    type TestArray struct {
        ArrayText string `json:"array_text,omitempty"`
    }
    type MainStructure struct {
        Text  string      `json:"text,omitempty"`
        Array []TestArray `json:"test_array,omitmepty"`
    }

    Test := MainStructure{
        Text: "test",
        Array: []TestArray{
            TestArray{ArrayText: "test1"},
            TestArray{ArrayText: "test2"},
        }}
    bytes, err := json.Marshal(Test)
    if err != nil {
        fmt.Println("eror marshalling")
    } else {
        fmt.Println(string(bytes))
    }
}

Check this out on play.golang.org

I could not get the point you wanted to use bytes.Buffer if your objective is just to put the result into the console. Assuming the point is:

  1. Create a struct instance (corresponding to a JSON object)
  2. Emit it in the screen

The following code can help you:

package main

import "encoding/json"
import "fmt"

type MainStructure struct {
    Text  string      `json:"text,omitempty"`
    Array []TestArray `json:"test_array,omitmepty"`
}

type TestArray struct {
    ArrayText string `json:"array_text,omitempty"`
}

func main() {
    Test := MainStructure{
        Text: "test",
        Array: []TestArray{
            TestArray{"test1"},
            TestArray{"test2"},
        },
    }

    res, _ := json.MarshalIndent(Test, "", "\t")
    fmt.Println(string(res))
}

json.MarshalIndent is used to make result pretty-formatted, if you bother it.