Go中包含非标准字段的结构数组上的MarshalJSON

Go中包含非标准字段的结构数组上的MarshalJSON,go,Go,我有以下几种: type IPFilePair struct { IP net.IP FileName string } type IPFilePairs []*IPFilePair 我正试图使用JSON.marshal(sample_ipfilepairs)封送此文件的JSON,但由于IP不是字符串,它会将其更改为奇怪的内容 将此输出IP的JSON作为字符串的正确方法是什么?我认为,如果您可以访问IPFilePair的定义,创建net.IP的本地typedef,并将其添加到

我有以下几种:

type IPFilePair struct {
    IP net.IP
    FileName string
}

type IPFilePairs []*IPFilePair
我正试图使用
JSON.marshal(sample_ipfilepairs)
封送此文件的JSON,但由于
IP
不是字符串,它会将其更改为奇怪的内容


将此输出
IP
的JSON作为字符串的正确方法是什么?

我认为,如果您可以访问
IPFilePair
的定义,创建
net.IP
的本地typedef,并将其添加到
marshanson()
中,就是一种方法:

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数据结构中,您需要使用
net.ParseIP
netIP
上实现
UnmarshalJSON()


我当然很好奇是否有人知道一种更简单的方法来实现这一点。

很遗憾,你不能直接将
MarshalJSON
方法添加到
net.IP
,但我想这是编译独立于完整程序的模块所需要的限制之一。@JamesHenstridge。同意。这是我所知道的最好的方法,但我希望比我更精通围棋的人会出现,并展示一个更简单的解决方案。另一种方法是在
IPFilePairs
级别实现
MarshalJSON
方法。您可以构建一个
map[string]接口{}
来保存字符串化的IP地址和文件名,并对其进行封送处理。这允许您直接使用
net.IP
,但在您想要嵌入IP地址的任何地方都会增加工作。