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

Comment comparer sémantiquement les structures et les tranches imbriquées quel que soit l'ordre des éléments dans Go

WBOY
Libérer: 2024-02-10 18:39:10
avant
844 Les gens l'ont consulté

无论 Go 中元素的顺序如何,如何在语义上比较结构与嵌套切片

Quel que soit l'ordre des éléments dans Go, comment comparer sémantiquement les structures par rapport aux tranches imbriquées est une question courante. Dans le langage Go, une structure est un type de données agrégé, tandis qu'une tranche est un tableau dynamique. L'éditeur PHP Zimo répondra à cette question pour vous. Lorsque l'on compare des structures, elles ne sont comparables que si tous les membres sont de types comparables. Lors de la comparaison de tranches imbriquées, nous devons comparer les éléments des tranches niveau par niveau. Si les types d'éléments de la tranche ne sont pas comparables, nous devons utiliser une méthode récursive pour comparer chaque élément de la tranche. Qu'il s'agisse d'une structure ou d'une tranche imbriquée, nous pouvons comparer des éléments en les itérant.

Contenu de la question

Donnez la définition suivante de la structure de type :

type A struct {
    Id  int
    Bs  []B
    Sub C
}

type B struct {
    Id  int
    Str string
}

type C struct {
    Id int
    Ds []D
}

type D struct {
    Id  int
    Num int
}
Copier après la connexion

Je souhaite tester si les deux instances suivantes de A sont sémantiquement égales quel que soit l'ordre des éléments de tranche à tous les niveaux hiérarchiques.

var want = &A{
    Id: 1,
    Bs: []B{{Id: 10, Str: "b10"}, {Id: 20, Str: "b20"}},
    Sub: C{
        Id: 100,
        Ds: []D{{Id: 101, Num: 1001}, {Id: 102, Num: 1002}},
    },
}

var got = &A{
    Id: 1,
    Bs: []B{{Id: 20, Str: "b20"}, {Id: 10, Str: "b10"}},
    Sub: C{
        Id: 100,
        Ds: []D{{Id: 102, Num: 1002}, {Id: 101, Num: 1001}},
    },
}
Copier après la connexion

Affirmez que la comparaison doit renvoyer true

Solution de contournement

Le package cmp est destiné à être un remplacement plus puissant et plus sûr de reflect.DeepEqual pour comparer deux valeurs pour l'égalité sémantique.

Voici une implémentation complète de la comparaison structurelle d'égalité sémantique quel que soit l'ordre des éléments de tranche à tous les niveaux hiérarchiques.

Fichier source.go

package main

type A struct {
    Id  int
    Bs  []B
    Sub C
}

type B struct {
    Id  int
    Str string
}

type C struct {
    Id int
    Ds []D
}

type D struct {
    Id  int
    Num int
}

func NewA() *A {
    return &A{
        Id: 1,
        Bs: []B{{Id: 20, Str: "b20"}, {Id: 10, Str: "b10"}},
        Sub: C{
            Id: 100,
            Ds: []D{{Id: 102, Num: 1002}, {Id: 101, Num: 1001}},
        },
    }
}
Copier après la connexion

Fichier source_test.go

package main

import (
    "fmt"
    "testing"

    "github.com/google/go-cmp/cmp"
    "github.com/google/go-cmp/cmp/cmpopts"
)

var want = &A{
    Id: 1,
    Bs: []B{{Id: 10, Str: "b10"}, {Id: 20, Str: "b20"}},
    Sub: C{
        Id: 100,
        Ds: []D{{Id: 101, Num: 1001}, {Id: 102, Num: 1002}},
    },
}

func TestNewA(t *testing.T) {
    got := NewA()
    less := func(x, y any) bool {
        switch xv := x.(type) {
        case B:
            yv := y.(B)
            return fmt.Sprintf("%d-%s", xv.Id, xv.Str) < fmt.Sprintf("%d-%s", yv.Id, yv.Str)
        case D:
            yv := y.(D)
            return fmt.Sprintf("%d-%d", xv.Id, xv.Num) < fmt.Sprintf("%d-%d", yv.Id, yv.Num)
        default:
            return false
        }
    }
    if diff := cmp.Diff(want, got, cmpopts.SortSlices(less)); diff != "" {
        t.Errorf("mismatch:\n%s", diff)
    }
}
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!

Étiquettes associées:
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
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!