dpitqpax07626 2017-05-11 10:23
浏览 277
已采纳

如果struct golang中的值是nil,0,false,则更新字段吗?

I have a struct:

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 has a few properties with nil (string), false (bool), 0 (int),... I want to check if a field of B is unassigned value, that field will receive value of the same field in A,

example:

B's About field is nil;

A's About field is "I am a admin" I want to B's About field is "I am a admin".

I can write code:

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

} Similar to other fields, I don't want check step by step with all of fields.

  • 写回答

2条回答 默认 最新

  • douyi5961 2017-05-11 15:43
    关注
    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
    ", ua)
        fmt.Printf("ub: %+v
    ", ub)
    
        err := Replace(ua, &ub)
        if err != nil {
            log.Fatal(err)
        }
    
        fmt.Printf("
    ua: %+v
    ", ua)
        fmt.Printf("ub: %+v
    ", 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
    }
    

    Output

    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}
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致