假设我有一个结构个人资料和sql表个人资料。
type Profile struct {
ID int `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Age int `json:"age"`
}
并且,我从 profiles 表中获取记录,并分配到Profile结构中。
这些字段允许为空,因此我使用 sql.NullString , sql.NullInt64 , pq.NullTime 在分配给struct之前检查有效值。
// ... DB.Query(...)
// ... rows.Next()
// ... rows.Scan()
// ...
if firstName.Valid {
p.FirstName = firstName.String
}
if lastName.Valid {
p.LastName = lastName.String
}
if age.Valid {
p.Age = age.Int64
}
// ...
如果我有超过10个表,每个表有超过30列,我必须一次又一次地检查所有变量。 这使得丑陋的代码,有人有任何建议让它漂亮吗?
答案 0 :(得分:3)
你根本不应该这样检查。可空类型旨在直接在结构中使用:
type Profile struct {
ID sql.NullInt64 `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
FirstName sql.NullString `json:"first_name"`
LastName sql.NullString `json:"last_name"`
Age sql.NullInt64 `json:"age"`
}
然后使用例如product.FirstName.String()
访问这些值。没有理由检查product.FirstName.Valid
,除非您真正关心nil
与空值之间的区别(在您的问题的示例中,您显然不关心这种区别)。
在某些情况下可能更适合的替代方法是使用指针:
type Profile struct {
ID *int `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
FirstName *string `json:"first_name"`
LastName *string `json:"last_name"`
Age *int `json:"age"`
}
当然,任何使用这些变量的代码都必须取消引用它们,并检查nil
,因此这可能并不总是最理想的,具体取决于您使用这些值的方式。
第三个选项,如果你从不关心NULL
值和空值之间的区别,那就是创建自己的类型,将它们视为相同。例如:
type myString string
func (s *myString) Scan(src interface{}) error {
if src == nil {
return nil
}
if value, ok := src.(string); ok {
*s = value
return nil
}
return fmt.Errorf("Unsupported type for myString: %T", src)
}