Maison > développement back-end > Golang > le corps du texte

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

WBOY
Libérer: 2024-02-12 18:30:09
avant
968 Les gens l'ont consulté

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"`
}
Copier après la connexion

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
}
Copier après la connexion

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)
    }
}
Copier après la connexion

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)
    }
}
Copier après la connexion

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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal