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
相关产品推荐
相关产品推荐

