golang:interface{}/[]interface{} to struct

440 阅读1分钟

为了存储结构的可扩展性,会在数据结构中加入一个扩展字段,大多时候会选择使用一个json字符串。但json中每个value都有自己的结构,比如字符串/struct/[]struct,解析的时候大致有两种思路:

  • 整个json解析为一个map[string]interface{},需要对应的key时拿到value再次解析
  • 针对当前的json结构,定义一个struct,直接解析为该机构

下面的例子是实现interface{}/[]interface{}与特定类型之间的转化,也是经常遇到的情形,demo如下:

interface{} to struct

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	kv := KV{
		Title:   "hello world",
		Content: "this is content",
	}
	//make a special to a common type, then we use the common type change to the special type
	common := CommonType{kv}
	byteData, _ := json.Marshal(common)

	common2 := CommonType{}
	json.Unmarshal(byteData, &common2)

	receiveCustomer := conveert(common2.Data)
	fmt.Println(receiveCustomer)
}

type KV struct {
	Title   string `json:"title"`
	Content string `json:"content"`
}

type CommonType struct {
	Data interface{} `json:"data"`
}

func conveert(data interface{}) KV {
	kv := KV{}
	bodyBytes, _ := json.Marshal(data)
	json.Unmarshal(bodyBytes, &kv)
	return kv
}

[]interface{} to struct

package main

import (
		"encoding/json"
	"fmt"
	)

	func main() {
		jsonstr := "{\"data\":[{\"title\": \"title1\", \"content\": \"content1\"}, {\"title\": \"title2\", \"content\": \"content2\"}]}"
		// we have a json string, the value is a list value, we need unmarshal the value to a kv list
		res := make(map[string][]interface{})
		json.Unmarshal([]byte(jsonstr), &res)
		receiveCustomer := convert(res["data"])
		fmt.Println(receiveCustomer)
	}

	type KV struct {
		Title   string `json:"title"`
		Content string `json:"content"`
	}


	func convert(data interface{}) []KV {
        kvs := []KV{}
        bodyBytes, _ := json.Marshal(data)
        json.Unmarshal(bodyBytes, &kvs)
        return kvs
    }