如何将不同的结构体存储在一个接口中以进行 JSON 序列化?

huangapple go评论81阅读模式
英文:

How to store different structs in a interface for json

问题

我只能直接让vA工作,如果我想根据我期望的JSON将A或B存储在vI中,我会得到以下错误:

json: 无法将对象解组为类型为main.TA的Go值

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type T interface {
	Printer()
}

type A struct{ JA string }

func (t A) Printer() { fmt.Print("A") }

type B struct{ JB string }

func (t B) Printer() { fmt.Print("B") }

var vA []A
var vB []B
var vI []T

func main() {
	// vA = []A{A{}}
	// vI = []T{B{}}
	vI = []T{A{}}
	get()
}

func get() {

	dec := json.NewDecoder(strings.NewReader("[{\"JA\":\"OK\"}]"))
	if err := dec.Decode(&vI); err != nil {
		fmt.Print(err)
	}

	for _, v := range vI {
		v.Printer()
	}

}

请帮我翻译一下。

英文:

http://play.golang.org/p/JJnU5ag234

I can only make vA work directly, if I want to use my vI to store A or B in it depending on the json I expect, I get

json: cannot unmarshal object into Go value of type main.TA

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type T interface {
	Printer()
}

type A struct{ JA string }

func (t A) Printer() { fmt.Print("A") }

type B struct{ JB string }

func (t B) Printer() { fmt.Print("B") }

var vA []A
var vB []B
var vI []T

func main() {
	// vA = []A{A{}}
	// vI = []T{B{}}
	vI = []T{A{}}
	get()
}

func get() {

	dec := json.NewDecoder(strings.NewReader("[{\"JA\":\"OK\"}]"))
	if err := dec.Decode(&vI); err != nil {
		fmt.Print(err)
	}

	for _, v := range vI {
		v.Printer()
	}

}

答案1

得分: 2

由于您希望解码器填充结构体的字段,您需要使用指针。像这样在类型的指针上定义接口的方法:http://play.golang.org/p/WUMt9Ok9Xp

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type T interface {
	Printer()
}

type A struct {
	JA string
}

func (a *A) Printer() {
	fmt.Printf("A: %v\n", a.JA)
}

type B struct {
	JB string
}

func (b *B) Printer() {
	fmt.Printf("B: %v\n", b.JB)
}

func main() {
	vI := []T{&A{}, &B{}}
	dec := json.NewDecoder(strings.NewReader("[{\"JA\":\"OKA\"}, {\"JB\":\"OKB\"}]"))
	if err := dec.Decode(&vI); err != nil {
		fmt.Print(err)
	}
	for _, v := range vI {
		v.Printer()
	}
}

希望对您有所帮助!

英文:

Since you expect the decoder to fill the fields of a struct, you have to use pointers. Define methods of the interface on the pointer of the type like this: http://play.golang.org/p/WUMt9Ok9Xp

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type T interface {
	Printer()
}

type A struct {
    JA string
}

func (a *A) Printer() {
    fmt.Printf("A: %v\n", a.JA)
}

type B struct {
    JB string
}

func (b *B) Printer() {
    fmt.Printf("B: %v\n", b.JB)
}

func main() {
    vI := []T{&A{}, &B{}}
	dec := json.NewDecoder(strings.NewReader("[{\"JA\":\"OKA\"}, {\"JB\":\"OKB\"}]"))
	if err := dec.Decode(&vI); err != nil {
    	fmt.Print(err)
	}
	for _, v := range vI {
    	v.Printer()
    }
}

huangapple
  • 本文由 发表于 2016年1月18日 10:29:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/34846401.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定