英文:
Avoid Code Duplication when unmarshalling similar json in go
问题
我正在努力想出一种优雅的方法来消除Go语言中的代码重复。ReadImageDataJson
和readJSON
函数基本上是相同的,只是它们返回不同的JSON格式。
package artworks
import (
"encoding/json"
"io/ioutil"
"log"
)
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"`
}
func ReadImageDataJson(filePath string) []ArtworksWithImageData {
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
}
var artworkData []ArtworksWithImageData
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
}
return artworkData
}
func readJSON(filePath string) []Artworks {
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
}
var artworkData []Artworks
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
}
return artworkData
}
我已经写出了如下代码:
func readJSON[T []Artworks | []ArtworksWithImageData](filePath string, jsonFormat T) T {
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
}
var artworkData T
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
}
return artworkData
}
但我不确定它是否真正有效,因为当我调用它时,例如readJson("myfile.json", []Artworks])
,我会得到错误[]Artworks (type) is not an expression
。
英文:
I'm struggling to come up with an elegant way of eliminating code duplication in Go. The ReadImageDataJson
and readJSON
functions are basically the same except they return different json formats.
package artworks
import (
"encoding/json"
"io/ioutil"
"log"
)
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"`
}
func ReadImageDataJson(filePath string) []ArtworksWithImageData {
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
}
var artworkData []ArtworksWithImageData
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
}
return artworkData
}
func readJSON(filePath string) []Artworks {
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
}
var artworkData []Artworks
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
}
return artworkData
}
I've got so far as writing this out:
func readJSON[T []Artworks | []ArtworksWithImageData](filePath string, jsonFormat T) T {
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
}
var artworkData T
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
}
return artworkData
}
But I'm not sure it really works because when I call it, i.e. readJson("myfile.json", []Artworks])
I get the error []Artworks (type) is not an expression
答案1
得分: 1
实际上,我刚刚弄清楚了!只需要在标签中添加omitempty
。
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"`
Imagedata string `json:"image_data,omitempty"`
}
func readJSON(filePath string) []Artworks {
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
}
var artworkData []Artworks
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
}
return artworkData
}
我还发现,如果你使用的是 Go 版本大于 1.18,你可以使用泛型来实现这个:
func readJSONGeneric[T Artwork | ArtworkWithImageData](filePath string) (T, error) {
var artworkData T
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
return artworkData, error
}
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
return artworkData, error
}
return artworkData, nil
}
英文:
Actually think I just figured this out! Just had to add omitempty
to the tag.
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"`
Imagedata string `json:"image_data,omitempty"`
}
func readJSON(filePath string) []Artworks {
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
}
var artworkData []Artworks
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
}
return artworkData
}
I also figured out you can do this with generics if you're on go > 1.18:
func readJSONGeneric[T Artwork | ArtworkWithImageData](filePath string) (T, error) {
var artworkData T
artworksList, error := ioutil.ReadFile(filePath)
if error != nil {
log.Fatalf("Error when opening file: %v", error.Error())
return artworkData, error
}
error = json.Unmarshal(artworksList, &artworkData)
if error != nil {
log.Fatalf("Error during unmarshal(): %v", error.Error())
return artworkData, error
}
return artworkData, nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论