Skip to content

Instantly share code, notes, and snippets.

@yoshinoyaussie
Created June 27, 2017 15:10
Show Gist options
  • Save yoshinoyaussie/9589a70dced6995637fe841ff9036f87 to your computer and use it in GitHub Desktop.
Save yoshinoyaussie/9589a70dced6995637fe841ff9036f87 to your computer and use it in GitHub Desktop.
Go言語で、できるだけお手軽かつ安全にシリアライズ⇒デシリアライズしてみる
package main
import (
"fmt"
"./serialize"
)
// Struct1 はテスト用の構造体1です。
type Struct1 struct {
Field1 string `json:"field1"`
Field2 []string `json:"field2"`
Field3 map[string]string `json:"field3"`
}
// Serializable はシリアライズ可能であることを示します。
func (s *Struct1) Serializable() {}
// Struct2 はテスト用の構造体2です。
type Struct2 struct {
Field1 string `json:"field1"`
Field2 Struct3 `json:"field2"`
}
// Serializable はシリアライズ可能であることを示します。
func (s *Struct2) Serializable() {}
// Struct3 はテスト用の構造体3です。
type Struct3 struct {
Field1 []string `json:"field1"`
}
// Serializable はシリアライズ可能であることを示します。
func (s *Struct3) Serializable() {}
func main() {
// Struct1のシリアライズ⇒デシリアライズ
testStruct1()
// Struct2のシリアライズ⇒デシリアライズ
testStruct2()
// Struct1のシリアライズ⇒Struct2にデシリアライズ(エラーになる)
testStruct1ToStruct2()
}
func testStruct1() {
fmt.Println("*** testStruct1() START")
// Struct1 のシリアライズ
a := Struct1{Field1: "test", Field2: []string{"1", "2"}, Field3: map[string]string{"test2": "3"}}
str, err := serialize.Serialize(&a)
if err != nil {
fmt.Println(err)
}
fmt.Println("Struct1 のシリアライズ結果 = " + str)
// Struct1 のデシリアライズ
b := Struct1{}
err = serialize.Deserialize(str, &b)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Struct1 のデシリアライズ結果 = %#v\n", b)
}
func testStruct2() {
fmt.Println("*** testStruct2() START")
// Struct2 (Struct3をフィールドとして持つ)のシリアライズ
a := Struct2{Field1: "ggg", Field2: Struct3{Field1: []string{"kkk", "lll"}}}
str, err := serialize.Serialize(&a)
if err != nil {
fmt.Println(err)
}
fmt.Println("Struct2 のシリアライズ結果 = " + str)
// Struct2 のデシリアライズ
b := Struct2{}
err = serialize.Deserialize(str, &b)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Struct2 のデシリアライズ結果 = %#v\n", b)
}
func testStruct1ToStruct2() {
fmt.Println("*** testStruct1ToStruct2() START")
// Struct1 のシリアライズ
a := Struct1{Field1: "test", Field2: []string{"1", "2"}, Field3: map[string]string{"test2": "3"}}
str, err := serialize.Serialize(&a)
if err != nil {
fmt.Println(err)
}
fmt.Println("Struct1 のシリアライズ結果 = " + str)
// Struct2 に Struct1 をデシリアライズしようとしてみる
b := Struct2{}
err = serialize.Deserialize(str, &b)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Struct1 のデシリアライズ結果 = %#v\n", b)
}
package serialize
import (
"encoding/json"
"errors"
"fmt"
"reflect"
"strings"
)
// serialize が返すエラーの定義
var (
ErrorTypeUnmatch = errors.New("Type Unmatch")
)
// Serializable はシリアライズ可能な構造体であることを示すinterfaceです。
type Serializable interface {
Serializable()
}
// Serialize はシリアライズを行います。
func Serialize(obj Serializable) (string, error) {
var serializeStr string
bytes, err := json.Marshal(obj)
if err != nil {
return serializeStr, err
}
serializeStr = fmt.Sprintf("%s\t%s", reflect.TypeOf(obj).String(), string(bytes))
return serializeStr, nil
}
// Deserialize はデシリアライズを行います。
func Deserialize(serializeStr string, resObj Serializable) error {
typeStr := reflect.TypeOf(resObj)
strs := strings.SplitN(serializeStr, "\t", 2)
if strs[0] != typeStr.String() {
return ErrorTypeUnmatch
}
err := json.Unmarshal([]byte(strs[1]), resObj)
if err != nil {
return err
}
return nil
}
@yoshinoyaussie
Copy link
Author

本コードの詳細については以下のQiita記事を参照してください。
http://qiita.com/y_ussie/items/58519d3e1b1427c959eb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment