在Go中,对于具有非标准字段的结构体数组进行MarshalJSON操作。

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

MarshalJSON on array of structs with non standard field in Go

问题

我有以下类型:

type IPFilePair struct {
    IP net.IP
    FileName string
}

type IPFilePairs []*IPFilePair

我试图使用json.Marshal(sample_ipfilepairs)将其转换为JSON,但是因为IP不是字符串,它将其转换为一些奇怪的东西。

如何正确地将输出的IP作为字符串转换为JSON?

英文:

I have the following types:

type IPFilePair struct {
    IP net.IP
    FileName string
}

type IPFilePairs []*IPFilePair

I'm trying to marshal the JSON of this using json.Marshal(sample_ipfilepairs) but because IP isn't a string, it changes it into something strange.

What is the proper way to make the JSON of this output IP as a string?

答案1

得分: 10

我认为,如果你可以访问IPFilePair的定义,那么创建一个本地的net.IP的typedef,并在其中添加MarshanJSON()是一个可行的方法:

package main

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

type netIP net.IP

type IPFilePair struct {
    IP netIP
	FileName string
}

type IPFilePairs []*IPFilePair

func (ip netIP) MarshalJSON() ([]byte, error) {
	return json.Marshal(net.IP(ip).String())
}

func main() {
	pair1 := IPFilePair{netIP{127, 0, 0, 1}, "file1"}
	pair2 := IPFilePair{netIP{127, 0, 0, 2}, "file2"}
	sample_ipfilepairs := IPFilePairs{&pair1, &pair2}

	b, _ := json.Marshal(sample_ipfilepairs)
	fmt.Println(string(b))
}

这将输出:

[{"IP":"127.0.0.1","FileName":"file1"},{"IP":"127.0.0.2","FileName":"file2"}]

当然,如果你需要将其反序列化回相同的Go数据结构,你需要在netIP上使用net.ParseIP实现UnmarshalJSON()

我当然很好奇是否有更简单的方法来实现这个。

英文:

I think if you have access to the definition of IPFilePair, creating local typedef of net.IP that you add MarshanJSON() to is the way to go:

package main

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

type netIP net.IP

type IPFilePair struct {
    IP netIP
	FileName string
}

type IPFilePairs []*IPFilePair

func (ip netIP) MarshalJSON() ([]byte, error) {
	return json.Marshal(net.IP(ip).String())
}

func main() {
	pair1 := IPFilePair{netIP{127, 0, 0, 1}, "file1"}
	pair2 := IPFilePair{netIP{127, 0, 0, 2}, "file2"}
	sample_ipfilepairs := IPFilePairs{&pair1, &pair2}

	b, _ := json.Marshal(sample_ipfilepairs)
	fmt.Println(string(b))
}

This outputs:

[{"IP":"127.0.0.1","FileName":"file1"},{"IP":"127.0.0.2","FileName":"file2"}]

Of course, if you ever need to unmarshal that back into the same Go data structure, you'll want to implement UnmarshalJSON() on netIP using net.ParseIP.

I'm certainly curious if anyone knows of an easier way to accomplish this.

huangapple
  • 本文由 发表于 2013年4月14日 14:52:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/15996539.html
匿名

发表评论

匿名网友

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

确定