Home > Backend Development > Golang > Override structure fields with values ​​from other 'part' structures

Override structure fields with values ​​from other 'part' structures

WBOY
Release: 2024-02-12 18:30:09
forward
998 people have browsed it

Override structure fields with values ​​from other part structures

php editor Xigua is here to introduce to you a method about using values ​​in other "part" structures to overwrite structure fields. In programming, we often need to update the values ​​of structure fields according to different situations. In this case, we can overwrite the fields in the target structure with values ​​from other structures. This method is very practical and can improve the readability and flexibility of the code. Next, I'll detail how to use this technique to simplify your code and make it more efficient.

Question content

I am new to Go and trying to create a CRUD API. Please forgive me that the OOP approach in Go may not be smart. I have a structure that I want to partially update via the PATCH endpoint.

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"`
}
Copy after login

I have defined a second structure that contains an updateable property for a book.

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

In both structures, I'm using (possibly abusing?) pointer attributes to simulate optional parameters. What I want to achieve is to overwrite a book with any given property in PatchBookDto. Here's what I've tried so far:

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)
    }
}
Copy after login

When I test this, I get the reflect.Value.Convert: value of type *string Cannot be converted to type string error.

Does anyone know what I can improve here to get what I need?

Workaround

Looks like you intended to put the panic line in the else block of if dtoField.Type.Kind() ==reflect.Ptr.

Another way is to use an indirect pointer and then set the value.

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)
    }
}
Copy after login

The above is the detailed content of Override structure fields with values ​​from other 'part' structures. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template