Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Cara membandingkan secara semantik struct vs hirisan bersarang tanpa mengira susunan elemen dalam Go

Cara membandingkan secara semantik struct vs hirisan bersarang tanpa mengira susunan elemen dalam Go

WBOY
WBOYke hadapan
2024-02-10 18:39:10845semak imbas

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

Tanpa mengira susunan elemen dalam Go, cara membandingkan struktur secara semantik berbanding kepingan bersarang ialah soalan biasa. Dalam bahasa Go, struktur ialah jenis data agregat, manakala kepingan ialah tatasusunan dinamik. Editor PHP Zimo akan menjawab soalan ini untuk anda. Apabila membandingkan struktur, ia boleh dibandingkan hanya jika semua ahli adalah jenis yang setanding. Apabila membandingkan kepingan bersarang, kita perlu membandingkan unsur-unsur dalam kepingan peringkat demi tahap. Jika jenis unsur hirisan tidak dapat dibandingkan, kita perlu menggunakan kaedah rekursif untuk membandingkan setiap elemen hirisan. Sama ada struct atau hirisan bersarang, kita boleh membandingkan elemen dengan mengulanginya.

Kandungan soalan

Berikan definisi struktur jenis seterusnya:

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
}

Saya ingin menguji sama ada dua kejadian seterusnya A adalah sama dari segi semantik tanpa mengira susunan elemen hirisan merentas semua peringkat hierarki.

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

Tegaskan bahawa perbandingan harus kembali benar

Penyelesaian

Pakej cmp bertujuan untuk menjadi pengganti yang lebih berkuasa dan lebih selamat untuk reflect.DeepEqual untuk membandingkan dua nilai untuk kesamaan semantik.

Berikut ialah pelaksanaan lengkap perbandingan struktur kesamaan semantik tanpa mengira susunan elemen hirisan pada semua peringkat hierarki.

Sumber fail.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}},
        },
    }
}

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

Atas ialah kandungan terperinci Cara membandingkan secara semantik struct vs hirisan bersarang tanpa mengira susunan elemen dalam Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam