Closed5

GoでMessagePackライブラリ作ってみる

nabeyangnabeyang

まずこんな感じで、MessagePackのarrayにマッピングするか、mapにマッピングするか選べるようにしたい。msgpack:"pair"ならmapとして、msgpack:"pair,array"ならarrayとして扱う。一番先頭だけ、これだと対応できないのでMarshal(origin, true)はarrayとしてMarshal(origin, false)はmapとして扱う。UnMarshalはデータから判断するので指定は不要。

func TestEncodeDecode(t *testing.T) {
	type Pair struct {
		X uint8 `msgpack:"x"`
		Y uint8 `msgpack:"y"`
	}
	type MixMap struct {
		ID   string `msgpack:"id"`
		Pair Pair   `msgpack:"pair"`
	}
	{
		var v MixMap
		origin := MixMap{
			ID: "abc",
			Pair: Pair{
				X: uint8(0x12),
				Y: uint8(0x34),
			},
		}
		data, _ := Marshal(origin, false)
		expect := "82a26964a3616263a47061697282a17812a17934"
		actual := hex.EncodeToString(data)
		if actual != expect {
			t.Errorf("expect '%s' but, got '%s'", expect, actual)
		}
		Unmarshal(data, &v)
		if origin != v {
			t.Errorf("origin %v but, got %v", origin, v)
		}
	}
	{
		var v MixMap
		origin := MixMap{
			ID: "abc",
			Pair: Pair{
				X: uint8(0x12),
				Y: uint8(0x34),
			},
		}
		data, _ := Marshal(origin, true)
		expect := "92a361626382a17812a17934"
		actual := hex.EncodeToString(data)
		if actual != expect {
			t.Errorf("expect '%s' but, got '%s'", expect, actual)
		}
		Unmarshal(data, &v)
		if origin != v {
			t.Errorf("origin %v but, got %v", origin, v)
		}
	}
}

nabeyangnabeyang

reflectでmapに値を入れる

main.go
package main

import (
	"fmt"
	"reflect"
)

func main() {
	var m map[string]string
	rv := reflect.ValueOf(&m).Elem()
	t := rv.Type()
	fmt.Println(rv.IsNil())// true
	rv.Set(reflect.MakeMap(t))
	fmt.Println(rv.IsNil())// false
	kt := t.Key()
	key := reflect.New(kt).Elem()
	key.SetString("A")
	vt := t.Elem()
	elem := reflect.New(vt).Elem()
	elem.SetString("hello")
	rv.SetMapIndex(key, elem)
	fmt.Println(m) // => map[A:hello]
}
nabeyangnabeyang

mapのデータ作るのに使った

find . -type f -ls | awk '{print $11, $5}'
このスクラップは2022/07/09にクローズされました