You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go中解析相似JSON时如何优雅消除代码重复?

Go语言消除JSON读取代码重复的优雅泛型实现

问题根源

你之前的调用错误是因为把类型[]Artworks当作函数参数传递,但Go的泛型调用需要通过类型参数列表指定类型,而非将类型作为参数传入。同时你定义的泛型函数里,jsonFormat参数完全多余——我们不需要传入实例,直接在函数内部初始化泛型类型变量即可。

正确泛型实现(推荐返回错误)

推荐将错误返回给调用者处理,而非直接log.Fatal退出,这样代码更灵活:

package artworks

import (
    "encoding/json"
    "fmt"
    "log"
    "os" // 用os.ReadFile替代废弃的ioutil.ReadFile
)

// 原结构体定义保持不变
type Artworks struct {
    Artist         string `json:"artist"`
    Tags           string `json:"tags"`
    Id             string `json:"id"`
    Thumbnail      string `json:"thumbnail"`
    High_res_image string `json:"high_res_image"`
    Date_uploaded  string `json:"date_uploaded"`
    Url            string `json:"url"`
}

type ArtworksWithImageData struct {
    Artworks
    Imagedata string `json:"image_data"`
}

// 泛型JSON读取函数,支持任意可反序列化的类型
func readJSON[T any](filePath string) (T, error) {
    artworksList, err := os.ReadFile(filePath)
    if err != nil {
        return *new(T), fmt.Errorf("打开文件失败: %w", err)
    }
    var artworkData T
    err = json.Unmarshal(artworksList, &artworkData)
    if err != nil {
        return *new(T), fmt.Errorf("JSON反序列化失败: %w", err)
    }
    return artworkData, nil
}

调用方式

调用时通过[类型]指定泛型参数:

// 读取[]Artworks类型数据
artworks, err := readJSON[[]Artworks]("myfile.json")
if err != nil {
    log.Fatal(err)
}

// 读取[]ArtworksWithImageData类型数据
artworksWithImage, err := readJSON[[]ArtworksWithImageData]("myfile.json")
if err != nil {
    log.Fatal(err)
}

保留log.Fatal风格的实现(可选)

如果你坚持沿用原函数直接退出的逻辑,泛型函数可以写成:

func readJSON[T any](filePath string) T {
    artworksList, err := os.ReadFile(filePath)
    if err != nil {
        log.Fatalf("Error when opening file: %v", err)
    }
    var artworkData T
    err = json.Unmarshal(artworksList, &artworkData)
    if err != nil {
        log.Fatalf("Error during unmarshal(): %v", err)
    }
    return artworkData
}

调用方式同样为:

artworks := readJSON[[]Artworks]("myfile.json")
artworksWithImage := readJSON[[]ArtworksWithImageData]("myfile.json")

关键说明

  • Go 1.18+才支持泛型,确保你的Go版本符合要求。
  • 用os.ReadFile替代ioutil.ReadFile:后者在Go 1.16后被标记为废弃,官方推荐使用os.ReadFile。
  • 泛型约束any表示任意类型,这里因为我们只需要类型支持JSON反序列化,any完全满足需求。

内容的提问来源于stack exchange,提问作者osint_alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 05:34:53