Go下encoding/json的Indent()接口以及Marshal()和MarshalIndent()的区别

通俗来讲,Indent()对读的结果做了一些处理,简单说就是对Json 多了一些格式处理。

而MarshalIndent()函数实现里就调用了饿Indent().

比如:

js,_ := json.Marshal(&person)
jsIndent,_ := json.MarshalIndent(&person, "", "\t")
fmt.Println("\njs:\n",string(js), "\n\njsIndent:\n",string(jsIndent)

打印:

        Go下encoding/json的Indent()接口以及Marshal()和MarshalIndent()的区别_第1张图片

 

  • MarshalIndent还可以设置前缀不为空

jsIndent,_ := json.MarshalIndent(&person, "haha", "\t")

结果:

          Go下encoding/json的Indent()接口以及Marshal()和MarshalIndent()的区别_第2张图片

  • MarshalIndent 方法的代码如下:

// MarshalIndent is like Marshal but applies Indent to format the output.
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
    b, err := Marshal(v)
    if err != nil {
        return nil, err
    }
    var buf bytes.Buffer
    err = Indent(&buf, b, prefix, indent)
    if err != nil {
        return nil, err
    }
    return buf.Bytes(), nil
}
  • 相比于Marhsal()的区别就在于读结果做了Indent 的处理: Indent 的代码有点长,简单说就是对Json 多了一些格式处理:
// Indent appends to dst an indented form of the JSON-encoded src.
// Each element in a JSON object or array begins on a new,
// indented line beginning with prefix followed by one or more
// copies of indent according to the indentation nesting.
// The data appended to dst does not begin with the prefix nor
// any indentation, to make it easier to embed inside other formatted JSON data.
// Although leading space characters (space, tab, carriage return, newline)
// at the beginning of src are dropped, trailing space characters
// at the end of src are preserved and copied to dst.
// For example, if src has no trailing spaces, neither will dst;
// if src ends in a trailing newline, so will dst.
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
    origLen := dst.Len()
    var scan scanner
    scan.reset()
    needIndent := false
    depth := 0
    for _, c := range src {
        scan.bytes++
        v := scan.step(&scan, c)
        if v == scanSkipSpace {
            continue
        }
        if v == scanError {
            break
        }
        if needIndent && v != scanEndObject && v != scanEndArray {
            needIndent = false
            depth++
            newline(dst, prefix, indent, depth)
        }

        // Emit semantically uninteresting bytes
        // (in particular, punctuation in strings) unmodified.
        if v == scanContinue {
            dst.WriteByte(c)
            continue
        }

        // Add spacing around real punctuation.
        switch c {
        case '{', '[':
            // delay indent so that empty object and array are formatted as {} and [].
            needIndent = true
            dst.WriteByte(c)

        case ',':
            dst.WriteByte(c)
            newline(dst, prefix, indent, depth)

        case ':':
            dst.WriteByte(c)
            dst.WriteByte(' ')

        case '}', ']':
            if needIndent {
                // suppress indent in empty object/array
                needIndent = false
            } else {
                depth--
                newline(dst, prefix, indent, depth)
            }
            dst.WriteByte(c)

        default:
            dst.WriteByte(c)
        }
    }
    if scan.eof() == scanError {
        dst.Truncate(origLen)
        return scan.err
    }
    return nil
}

处理格式:

               Go下encoding/json的Indent()接口以及Marshal()和MarshalIndent()的区别_第3张图片

你可能感兴趣的:(Go)