Golang中如何将值数组和头信息反序列化到结构体
Golang中如何将值数组和头信息反序列化到结构体 我正在尝试将CSV中的用户逐一解析到其对应的结构体。但我不确定实现此目标的最佳方式或方法是什么。请查看以下代码。任何帮助都将不胜感激。
recordFile, err := os.Open(csv_file_path)
if err != nil {
return "Couldnt open file"
}
reader := csv.NewReader(recordFile)
headers, err := reader.Read()
if err != nil {
return "Couldnt get headers"
}
fmt.Printf("Headers : %v \n", headers)
var user user_schema.User
for i := 0; ; i = i + 1 {
record, err := reader.Read()
if err == io.EOF {
break // reached end of the file
} else if err != nil {
return "Error in retrieving record"
}
eerr := json.Unmarshal(record, &user) // <- Problem is here, how do I convert headers and array of values to User struct
if eerr != nil {
panic(eerr)
}
}
更多关于Golang中如何将值数组和头信息反序列化到结构体的实战教程也可以访问 https://www.itying.com/category-94-b0.html
4 回复
我正在尝试从CSV文件向数据库填充数据(将使其动态化,以便传递任何表结构及其CSV文件路径,即可随时填充数据)。
更多关于Golang中如何将值数组和头信息反序列化到结构体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Read 方法返回一个 []string。你需要遍历这个切片(针对表头行)来获取列名。然后针对每一行,遍历该行的 []string 切片。
顺便问一下:user_schema.User 是什么?
// 代码示例应放在这里
lutzhorn:
user_schema.User是什么?
type User struct {
ID uint `gorm:"primary_key"`
UserName string `validate:"required"`
Email string `validate:"required,email"`
PwdHash string `validate:"required" json:"pwd_hash"`
Password string `gorm:"-"`
PhoneNumber string
IsActive int8
LastActive string
CreatedAt time.Time
UpdatedAt time.Time
}
在Golang中,将CSV的头部信息和值数组反序列化到结构体,可以使用reflect包动态映射字段。以下是实现示例:
package main
import (
"encoding/csv"
"fmt"
"io"
"os"
"reflect"
"strings"
)
type User struct {
ID string `csv:"id"`
Name string `csv:"name"`
Email string `csv:"email"`
}
func UnmarshalCSV(headers []string, record []string, v interface{}) error {
val := reflect.ValueOf(v).Elem()
typ := val.Type()
headerMap := make(map[string]int)
for i, header := range headers {
headerMap[strings.ToLower(header)] = i
}
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
fieldType := typ.Field(i)
tag := fieldType.Tag.Get("csv")
if tag == "" {
tag = strings.ToLower(fieldType.Name)
}
if idx, ok := headerMap[tag]; ok && idx < len(record) {
field.SetString(record[idx])
}
}
return nil
}
func main() {
recordFile, err := os.Open("users.csv")
if err != nil {
panic(err)
}
defer recordFile.Close()
reader := csv.NewReader(recordFile)
headers, err := reader.Read()
if err != nil {
panic(err)
}
fmt.Printf("Headers: %v\n", headers)
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
var user User
if err := UnmarshalCSV(headers, record, &user); err != nil {
panic(err)
}
fmt.Printf("User: %+v\n", user)
}
}
对于更复杂的场景,可以使用第三方库gocarina/gocsv:
package main
import (
"encoding/csv"
"fmt"
"os"
"github.com/gocarina/gocsv"
)
type User struct {
ID string `csv:"id"`
Name string `csv:"name"`
Email string `csv:"email"`
}
func main() {
file, err := os.Open("users.csv")
if err != nil {
panic(err)
}
defer file.Close()
var users []User
if err := gocsv.UnmarshalCSV(csv.NewReader(file), &users); err != nil {
panic(err)
}
for _, user := range users {
fmt.Printf("User: %+v\n", user)
}
}
如果需要处理动态头部,可以使用mapstructure库:
package main
import (
"encoding/csv"
"fmt"
"io"
"os"
"github.com/mitchellh/mapstructure"
)
func main() {
file, err := os.Open("users.csv")
if err != nil {
panic(err)
}
defer file.Close()
reader := csv.NewReader(file)
headers, err := reader.Read()
if err != nil {
panic(err)
}
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
data := make(map[string]interface{})
for i, header := range headers {
if i < len(record) {
data[header] = record[i]
}
}
var user struct {
ID string `mapstructure:"id"`
Name string `mapstructure:"name"`
Email string `mapstructure:"email"`
}
if err := mapstructure.Decode(data, &user); err != nil {
panic(err)
}
fmt.Printf("User: %+v\n", user)
}
}
这些示例展示了如何将CSV头部和值数组映射到结构体字段。

