MST

星途 面试题库

面试题:Go语言切片与JSON转换中的嵌套结构及自定义编码处理

给定一个复杂的嵌套结构的切片,例如切片中的元素是包含嵌套结构体且结构体中部分字段需要自定义JSON编码格式(如时间字段需要特定的格式化输出),请实现将此切片转换为JSON数据,以及将对应的JSON数据再转换回切片的完整Go语言代码,并解释实现过程中涉及的原理和关键技术点。
10.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

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

// 自定义时间格式结构体
type CustomTime struct {
    time.Time
}

// 实现MarshalJSON方法,用于自定义JSON编码格式
func (ct CustomTime) MarshalJSON() ([]byte, error) {
    // 自定义时间格式
    formattedTime := ct.Time.Format("2006-01-02 15:04:05")
    return []byte(`"` + formattedTime + `"`), nil
}

// 实现UnmarshalJSON方法,用于自定义JSON解码格式
func (ct *CustomTime) UnmarshalJSON(b []byte) error {
    var err error
    // 去除双引号
    s := string(b[1 : len(b)-1])
    // 解析时间
    ct.Time, err = time.Parse("2006-01-02 15:04:05", s)
    return err
}

// 嵌套结构体
type InnerStruct struct {
    ID   int
    Name string
    Time CustomTime
}

// 外层结构体
type OuterStruct struct {
    Inner InnerStruct
}

// 主函数
func main() {
    // 初始化切片
    dataSlice := []OuterStruct{
        {Inner: InnerStruct{ID: 1, Name: "Alice", Time: CustomTime{Time: time.Now()}}},
        {Inner: InnerStruct{ID: 2, Name: "Bob", Time: CustomTime{Time: time.Now()}}},
    }

    // 转换为JSON数据
    jsonData, err := json.MarshalIndent(dataSlice, "", "  ")
    if err != nil {
        fmt.Println("Marshal error:", err)
        return
    }
    fmt.Println("JSON data:\n", string(jsonData))

    // 从JSON数据转换回切片
    var newSlice []OuterStruct
    err = json.Unmarshal(jsonData, &newSlice)
    if err != nil {
        fmt.Println("Unmarshal error:", err)
        return
    }
    fmt.Println("New slice:", newSlice)
}

原理和关键技术点解释

  1. 自定义JSON编码格式
    • 为了实现时间字段的特定格式化输出,我们定义了一个CustomTime结构体,它嵌入了Go语言标准库中的time.Time结构体。
    • 通过为CustomTime结构体实现MarshalJSON方法,我们可以控制该结构体在转换为JSON时的格式。在MarshalJSON方法中,我们使用time.Format函数将时间格式化为指定的字符串,然后再封装成JSON格式的字节切片返回。
  2. 自定义JSON解码格式
    • 同样为CustomTime结构体实现UnmarshalJSON方法,用于在从JSON数据转换回Go结构体时,解析自定义格式的时间字符串。在UnmarshalJSON方法中,我们先去除JSON字符串的双引号,然后使用time.Parse函数将字符串解析为time.Time类型。
  3. 嵌套结构体处理
    • 我们定义了InnerStructOuterStruct两个结构体,InnerStruct包含了需要自定义JSON编码格式的时间字段,OuterStruct嵌套了InnerStruct
    • 当使用json.Marshaljson.Unmarshal时,Go语言的JSON包会递归地处理嵌套结构体,自动调用我们为CustomTime定义的MarshalJSONUnmarshalJSON方法。
  4. json.Marshaljson.Unmarshal
    • json.Marshal函数用于将Go语言的数据结构转换为JSON格式的字节切片。json.MarshalIndent函数则可以格式化输出,使JSON数据更易读。
    • json.Unmarshal函数用于将JSON格式的字节切片转换回Go语言的数据结构。在使用时,需要传入指向目标数据结构的指针。