首頁  >  文章  >  後端開發  >  使用其他“部分”結構中的值覆蓋結構字段

使用其他“部分”結構中的值覆蓋結構字段

WBOY
WBOY轉載
2024-02-12 18:30:09967瀏覽

使用其他“部分”結構中的值覆蓋結構字段

php小編西瓜在這裡為大家介紹一個有關使用其他「部分」結構中的值覆寫結構欄位的方法。在程式設計中,我們經常需要根據不同的情況來更新結構欄位的值。在這種情況下,我們可以使用其他結構中的值來覆寫目標結構中的欄位。這種方法非常實用,可以提高程式碼的可讀性和靈活性。接下來,我將詳細介紹如何使用此技巧來簡化程式碼並提高效率。

問題內容

我是 Go 新手,正在嘗試建立 CRUD API。請原諒 Go 中的 OOP 方法可能不聰明。我有一個結構,我想透過 PATCH 端點進行部分更新。

type Book struct {
  Id        uuid.UUID  `json:"id"`
  Author    uuid.UUID  `json:"author"`
  Title     string     `json:"title"`
  IsPublic  bool       `json:"isPublic"`
  CreatedAt time.Time  `json:"createdAt"`
  UpdatedAt *time.Time `json:"updatedAt"`
  DeletedAt *time.Time `json:"deletedAt"`
}

我已經定義了第二個結構體,其中包含一本書的可更新屬性。

type PatchBookDto struct {
  Author   *uuid.UUID
  Title    *string
  IsPublic *bool
}

在這兩個結構中,我都使用(可能濫用?)指標屬性來模擬可選參數。我想要實現的是用 PatchBookDto 中的任何給定屬性覆蓋一本書。這是我迄今為止的嘗試:

var book models.Book // Is taken from an array of books
var dto dtos.PatchBookDto

if err := c.BindJSON(&dto); err != nil {
    // Abort
}

dtoTypeInfo := reflect.TypeOf(&dto).Elem()

for i := 0; i < dtoTypeInfo.NumField(); i++ {
    dtoField := dtoTypeInfo.Field(i)
    bookField := reflect.ValueOf(&book).Elem().FieldByName(dtoField.Name)

    if bookField.IsValid() && bookField.CanSet() {

        dtoValue := reflect.ValueOf(dto).Field(i)

        if dtoValue.Interface() == reflect.Zero(dtoValue.Type()).Interface() {
            continue
        }

        if dtoField.Type.Kind() == reflect.Ptr {
            if dtoValue.Elem().Type().AssignableTo(bookField.Type()) {
                bookField.Set(dtoValue.Elem())
            } else {
                // Abort
            }
        }

        convertedValue := dtoValue.Convert(bookField.Type())
        bookField.Set(convertedValue)
    }
}

當我測試這個時,我收到 reflect.Value.Convert: value of type *string Cannot be conversion to type string 錯誤。

有人知道我可以在這裡改進什麼以獲得我需要的東西嗎?

解決方法

看起來您打算將恐慌行放在 if dtoField.Type.Kind() ==reflect.Ptr 的 else 區塊中。

另一種方法是使用間接指針,然後設定值。

for i := 0; i < dtoTypeInfo.NumField(); i++ {
    dtoField := dtoTypeInfo.Field(i)
    bookField := reflect.ValueOf(&book).Elem().FieldByName(dtoField.Name)
    if bookField.IsValid() && bookField.CanSet() {
        dtoValue := reflect.ValueOf(dto).Field(i)
        if dtoValue.Interface() == reflect.Zero(dtoValue.Type()).Interface() {
            continue
        }
        dtoValue = reflect.Indirect(dtoValue)
        convertedValue := dtoValue.Convert(bookField.Type())
        bookField.Set(convertedValue)
    }
}

以上是使用其他“部分”結構中的值覆蓋結構字段的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除