Skip to content

Instantly share code, notes, and snippets.

@birowo
Last active June 11, 2018 04:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save birowo/03889aced8ea20c422a45846f4b060a2 to your computer and use it in GitHub Desktop.
Save birowo/03889aced8ea20c422a45846f4b060a2 to your computer and use it in GitHub Desktop.
golang: implementasi fungsi Marshal khusus untuk map & bukan untuk struct . playground: https://play.golang.org/p/nnyHUcCdyaA

fungsi Marshal di package encoding/json bisa di pakai baik untuk data type struct maupun data type map sehingga implementasinya harus pakai reflect: https://golang.org/src/encoding/json/encode.go?s=6456:6499#L298 . saya buat fungsi Marshal khusus untuk data type map saja & tidak untuk data type struct sehingga implementasinya bisa tanpa reflect sehingga performa bisa lebih baik

jsonmap

untuk cek kebenaran hasil, bisa pakai JSON.parse di konsol browser:

jsonmap_konsolbrowser

package main
import (
"bytes"
"strconv"
)
func fKV(rslt *bytes.Buffer, v KV) {
i := len(v)
rslt.WriteByte('{')
for _k, _v := range v {
rslt.WriteByte('"')
rslt.WriteString(_k)
rslt.WriteString(`":`)
Marshal(rslt, _v)
i--
if i == 0 {
rslt.WriteByte('}')
return
}
rslt.WriteByte(',')
}
}
func fSlc(rslt *bytes.Buffer, v Slc) {
last := len(v) - 1
rslt.WriteByte('[')
for _, _v := range v[:last] {
Marshal(rslt, _v)
rslt.WriteByte(',')
}
Marshal(rslt, v[last])
rslt.WriteByte(']')
}
func Marshal(rslt *bytes.Buffer, v interface{}) {
switch v.(type) {
case string:
rslt.WriteByte('"')
rslt.WriteString(v.(string))
rslt.WriteByte('"')
case int:
rslt.WriteString(strconv.FormatInt(int64(v.(int)), 10))
case float64:
rslt.WriteString(strconv.FormatFloat(v.(float64), 'f', -1, 64))
case KV:
fKV(rslt, v.(KV))
case Slc:
fSlc(rslt, v.(Slc))
default:
println("unsupported type")
}
}
type (
KV map[string]interface{}
Slc []interface{}
)
func main() {
kv := KV{
"a": 123,
"b": Slc{1, 2},
"c": 1.23,
"d": Slc{1.2, 2.3},
"e": KV{"a": 123},
"f": Slc{KV{"a": 12}, KV{"b": 23}},
"g": "abc",
"h": Slc{"ab", "bc"},
}
var rslt bytes.Buffer
Marshal(&rslt, kv)
println(rslt.String())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment