Maison  >  Article  >  développement back-end  >  Remplacer les champs de structure par des valeurs provenant d'autres structures "parties"

Remplacer les champs de structure par des valeurs provenant d'autres structures "parties"

WBOY
WBOYavant
2024-02-12 18:30:09920parcourir

Remplacer les champs de structure par des valeurs provenant dautres structures parties

L'éditeur php Xigua est là pour vous présenter une méthode d'utilisation des valeurs dans d'autres structures "parties" pour écraser les champs de structure. En programmation, nous avons souvent besoin de mettre à jour les valeurs des champs de structure en fonction de différentes situations. Dans ce cas, nous pouvons écraser les champs de la structure cible par des valeurs d'autres structures. Cette méthode est très pratique et peut améliorer la lisibilité et la flexibilité du code. Ensuite, je détaillerai comment utiliser cette technique pour simplifier votre code et le rendre plus efficace.

Contenu de la question

Je suis nouveau sur Go et j'essaie de créer une API CRUD. Veuillez me pardonner que l'approche POO dans Go n'est peut-être pas intelligente. J'ai une structure que je souhaite mettre à jour partiellement via le point de terminaison 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"`
}

J'ai défini une deuxième structure qui contient une propriété pouvant être mise à jour pour un livre.

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

Dans les deux structures, j'utilise (peut-être en abusant ?) des attributs de pointeur pour simuler des paramètres facultatifs. Ce que je veux réaliser, c'est écraser un livre avec une propriété donnée dans PatchBookDto. Voici ce que j'ai essayé jusqu'à présent :

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)
    }
}

Lorsque j'ai testé cela, j'ai eu l'erreur reflect.Value.Convert: value of type *string Cannot be conversion to type string.

Est-ce que quelqu'un sait ce que je peux améliorer ici pour obtenir ce dont j'ai besoin ?

Solution de contournement

On dirait que vous avez l'intention de mettre la ligne de panique dans le bloc if dtoField.Type.Kind() ==reflect.Ptr else.

Une autre façon consiste à utiliser un pointeur indirect, puis à définir la valeur.

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)
    }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer