不同結構轉換
不同結構轉轉後換
因為斷言只能用在相同結構的轉換,而相似結構的轉換則要用不同方式去進行.
type UserDetail struct {
Name string `json:"name"`
Email string `json:"email"`
BirthDay string
Addr string
Phone string
Age int `json:"age"`
Order []order
}
type UserDetail2 struct {
Name string
Email string
BirthDay string
Addr string
Phone string
Age int
Order []order
}
type UserBrief struct {
Name string `json:"name"`
Email string `json:"email"`
Age int
Order []order
}
type order struct {
ID string
Name string
}
func main() {
user1 := UserDetail{Name: "anna", Age: 20, Addr: "star", Phone: "123456789", Email: "test@test.com",
Order: []order{{ID: "01", Name: "name1"}, {ID: "02", Name: "name2"}},
}
fmt.Printf("Type:%T V(%v) Name:%s \n", user1, user1, user1.Name)
user2 := UserDetail2(user1) //使用斷言 T(v) 相同結構struct(忽略struct tag)
fmt.Printf("Type:%T V(%v) Name:%s \n", user2, user2, user2.Name)
//user3 := UserBrief(user1) // 不能使用斷言 因為結構不同 會報錯 cannot convert user1 (variable of type UserDetail) to UserBriefcompiler
}
方法一
//方式一:自己寫轉換 一個欄位一個欄位對應
//缺點:如果欄位太多會寫到懷疑自己,而且容易漏
//優點 : 性能較好,可以自己處理錯誤訊息
func toUserBrief(payload UserDetail, u *UserBrief) error {
if payload.Name == "" {
return errors.Errorf("payload name empty")
}
u.Age = payload.Age
u.Name = payload.Name
u.Email = payload.Email
return nil
}
方法二
//使用第三方套件:copier.Copy轉換
func toUserBriefCopier(to *UserBrief, from *UserDetail) error {
//Copy(toValue interface{}, fromValue interface{})
err := copier.Copy(to, from)
if err != nil {
return err
}
return nil
}
方法三 : 使用SandardJson
但使用這方法要注意效能問題,也有其他easyJson,fastJson可替換.
func ToUserSandardJsonMarshal(to *UserBrief, from *UserDetail) error {
b, err := json.Marshal(from)
if err != nil {
return errors.Wrap(err, "marshal from data err")
}
err = json.Unmarshal(b, to)
if err != nil {
return errors.Wrap(err, "unmarshal to data err")
}
return nil
}
參考
Last updated