用Golang进行字符串分割的自定义反序列化

4
我有以下JSON: {"student_number":1234567, "name":"John Doe", "subjects":"Chemistry-Maths-History-Geography"} 我想要将它解析到一个结构体中,其中一个项目(科目)会被拆分成一个 []string
type Student struct {
  StudentNumber int       `json:"student_number"`
  Name          string    `json:"name"`
  Subjects []string 
}

我尝试了几种使用 strings.Split() 自定义解组的方法,但目前为止都没有成功。

在解组过程中有没有什么方法可以实现这一点?或者我需要简单地解组,然后进行转换?


2
当然,你可以编写自己的UnmarshalJSON方法来完成这个任务。但是为什么要费事呢?直接将其解组成字符串,然后拆分会更简单、更容易测试,而且更不容易出错。 - Volker
1个回答

17

最简单的方法是定义自己的字符串切片类型,并在上面实现json.Unmarshaler

type strslice []string

func (ss *strslice) UnmarshalJSON(data []byte) error {
    var s string
    if err := json.Unmarshal(data, &s); err != nil {
        return err
    }
    *ss = strings.Split(s, "-")
    return nil
}

并在你的结构体中使用它:

type Student struct {
    StudentNumber int      `json:"student_number"`
    Name          string   `json:"name"`
    Subjects      strslice `json:"subjects"`
}

然后它就会工作:

func main() {
    var s Student
    err := json.Unmarshal([]byte(src), &s)
    fmt.Println(s, err)
}

const src = `{"student_number":1234567, "name":"John Doe", "subjects":"Chemistry-Maths-History-Geography"}`

输出结果(可以在Go Playground上尝试):

{1234567 John Doe [Chemistry Maths History Geography]} <nil>

1
像阳光一样工作。谢谢!您是否同意Volker的评论,认为在取消编组后执行此操作实际上是更好的解决方案? - MarcoW
1
@MarcoW 这取决于您的使用情况。如果您只需要一次切片,可以将字段保留为结构体中的“string”,并向结构体添加一个方法来分割它(或者在需要时仅拆分字段值)。如果您需要多次使用它,则可以存储已分裂的部分(例如,在附加字段中),但此时该解决方案更简单。 - icza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接