【问题标题】:Update field if value is nil, 0, false in struct golang?如果结构golang中的值为nil,0,false,则更新字段?
【发布时间】:2017-10-10 07:09:11
【问题描述】:

我有一个结构:

type User struct {
   ID       int    `json:"id"`
   Username string `json:"username"`
   About    string `json:"about"`
   IsAdmin  bool   `json:"is_admin"`
   Status   int    `json:"status"`
   ......
}
A:= User{1,"admin", "I am a admin",status: 1,....}
B:= User{ID:1, Username: "UserBBBB"}
...enter code here...
B is {1, "UserBBBB", "I am a admin", 1, ...(same value in A)}

object B 有一些属性,nil (string), false (bool), 0 (int),... 我想检查 B 的字段是否未分配值,该字段将接收 A 中相同字段的值,

示例:

B 的 About 字段为零;

A 的 About 字段是“我是管理员” 我想 B 的 About 字段是“我是管理员”。

我会写代码:

if len(B.About) == 0 {
  B.About = A.About

} 与其他字段类似,我不想一步步检查所有字段。

【问题讨论】:

  • 您可能想重新表述您的问题。我看了 4 遍,还是不知道你的问题是什么。
  • 我的问题更新了,非常感谢!
  • 好的,现在我明白了。这是可行的,以一种通用的方式,但这需要使用反射包。如果性能对您来说不是问题,则可以考虑。
  • 你可以帮助我一个简单的小代码。我不知道如何解决这个问题。
  • 我正在写。

标签: go struct null


【解决方案1】:

如果我正确理解您要完成的工作,您最好使用指向对象的指针而不是对象。

例如,

A := &User{1,"admin", "I am a admin",status: 1,....}
if A != nil {
  fmt.Println(A)
} else {
  fmt.Println("nil object")
}

没有理由检查对象的字段是否为默认值。

【讨论】:

  • 对不起。只有少数字段是默认值
【解决方案2】:
package main

import (
    "errors"
    "fmt"
    "log"
    "reflect"
    "time"
)

type User struct {
    ID       int    `json:"id"`
    Username string `json:"username"`
    About    string `json:"about"`
    IsAdmin  bool   `json:"is_admin"`
    Status   int    `json:"status"`
    Date     *time.Time
}

func main() {
    now := time.Now()
    ua := User{
        ID:       1,
        Username: "admin",
        About:    "I am an admin",
        IsAdmin:  true,
        Status:   1,
        Date:     &now,
    }
    ub := User{
        Username: "user",
    }

    fmt.Printf("ua: %+v\n", ua)
    fmt.Printf("ub: %+v\n", ub)

    err := Replace(ua, &ub)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("\nua: %+v\n", ua)
    fmt.Printf("ub: %+v\n", ub)
}

// IsZeroOfUnderlyingType return wether x is the is
// the zero-value of its underlying type.
func IsZeroOfUnderlyingType(x interface{}) bool {
    return reflect.DeepEqual(x, reflect.Zero(reflect.TypeOf(x)).Interface())
}

// Replace replaces all fields of struct b that have a
// zero-value with the corresponding field value from a.
// b must be a pointer to a struct.
func Replace(a, b interface{}) error {
    // Check a.
    va := reflect.ValueOf(a)
    if va.Kind() != reflect.Struct {
        return errors.New("a is not a struct")
    }
    // Check b.
    vb := reflect.ValueOf(b)
    if vb.Kind() != reflect.Ptr {
        return errors.New("b is not a pointer")
    }
    // vb is a pointer, indirect it to get the
    // underlying value, and make sure it is a struct.
    vb = vb.Elem()
    if vb.Kind() != reflect.Struct {
        return errors.New("b is not a struct")
    }
    for i := 0; i < vb.NumField(); i++ {
        field := vb.Field(i)
        if field.CanInterface() && IsZeroOfUnderlyingType(field.Interface()) {
            // This field have a zero-value.
            // Search in a for a field with the same name.
            name := vb.Type().Field(i).Name
            fa := va.FieldByName(name)
            if fa.IsValid() {
                // Field with name was found in struct a,
                // assign its value to the field in b.
                if field.CanSet() {
                    field.Set(fa)
                }
            }
        }
    }
    return nil
}

输出

ua: {ID:1 Username:admin About:I am an admin IsAdmin:true Status:1 Date:2017-05-11 17:47:30.805657327 +0200 CEST}
ub: {ID:0 Username:user About: IsAdmin:false Status:0 Date:<nil>}

ua: {ID:1 Username:admin About:I am an admin IsAdmin:true Status:1 Date:2017-05-11 17:47:30.805657327 +0200 CEST}
ub: {ID:1 Username:user About:I am an admin IsAdmin:true Status:1 Date:2017-05-11 17:47:30.805657327 +0200 CEST}

【讨论】:

  • 非常感谢!如果我解决了我的问题,我会检查你的代码并投票。再次感谢!
  • 欢迎您。我认为代码足以让您理解,但如果我是您,我会仔细查看反射包。
  • 我爱你,你很热情
猜你喜欢
  • 1970-01-01
  • 2018-05-03
  • 2020-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
  • 2016-10-11
相关资源
最近更新 更多