Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Parameter jenis mengekang selanjutnya dalam Golang (menggunakan kaedah Mengandungi untuk melaksanakan Senarai generik)

Parameter jenis mengekang selanjutnya dalam Golang (menggunakan kaedah Mengandungi untuk melaksanakan Senarai generik)

WBOY
WBOYke hadapan
2024-02-06 08:15:04565semak imbas

Parameter jenis mengekang selanjutnya dalam Golang (menggunakan kaedah Mengandungi untuk melaksanakan Senarai generik)

Kandungan soalan

Andaikan saya ingin menulis jenis list generik yang mengandungi beberapa kaedah berguna seperti:

type list[t any] []t

func (l *list[t]) len() int
func (l *list[t]) get(pos int) (t t, err error)
func (l *list[t]) set(pos int, t t) error
func (l *list[t]) append(t ...t)
func (l *list[t]) insert(t t, pos int) error
func (l *list[t]) remove(pos int) (t t, err error)
// etc...

Walau bagaimanapun, terdapat kaedah berguna lain yang mungkin memerlukan pengehadan lagi jenis elemen senarait. Sebagai contoh, kami tidak boleh melaksanakan kaedah mengandungi pada jenis t。例如,我们无法在此 list 类型上实现 contains ini:

func (l *list[t]) contains(t t) bool {
    for _, s := range *l {
        if s == t { // compiler error: invalid operation: s == t (incomparable types in type set)
            return true
        }
    }
    return false
}

Kami hanya boleh melaksanakan mengandungilist 为,我们只能实现 contains jika kami mengisytiharkan

sebagai
type List[T comparable] []T

Tetapi ini menjadikannya mustahil untuk mencipta jenis yang tiada tandingan list .

Adakah terdapat cara untuk mendapatkan yang terbaik dari kedua-dua dunia? I.e. adakah kaedah tlist[t] ,但在 t 具有可比性的情况下允许它有一个 contains tersedia untuk jenis yang tiada tandingan?

Saya terfikir tentang:

  • Gunakan jenis yang berbeza (cth. uncomparablelist/uncomparablelist/listlist/comparablelist atau
  • /comparablelist)
  • 包含 Jadikan
  • fungsi dan bukannya kaedah

Tetapi saya tidak begitu menyukai mana-mana daripada mereka.

Jawapan betul

go tidak mempunyai pengkhususan, jadi saya rasa anda tidak boleh membuatnya berfungsi dengan tepat seperti ini (bukan pakar generik).

Saya rasa cara yang munasabah untuk menyelesaikan masalah ini ialah dengan lulus pembanding yang jelas:

func (l *list[t]) contains(t t, cmp func(t, t) bool) bool {
    for _, s := range *l {
        if cmp(s, t) {
            return true
        }
    }
    return false
}

Maka bolehlah

func main() {
    list := list[int]([]int{1,2,3})
    fmt.println(list.contains(2, func(a, b int) bool { return a == b })) // true
}

Untuk jenis yang serupa, anda boleh memberikan nilai lalai:

func eq[t comparable](a, b t) bool {
    return a == b
}

Jadi perkara di atas menjadi

func main() {
    list := List[int]([]int{1,2,3})
    fmt.Println(list.Contains(2, Eq[int]) // true
}
list 类型中嵌入一个比较器,并为其指定默认值 func(a, b t) bool { return false }Anda juga boleh membenamkan pembanding dalam jenis

dan memberikan nilai lalai func(a, b t) bool { return false } dan mendedahkan pembanding tersuai yang boleh dihantar ke dalamnya Constructor. Tetapi ini mungkin terlalu kabur untuk anda. 🎜

Atas ialah kandungan terperinci Parameter jenis mengekang selanjutnya dalam Golang (menggunakan kaedah Mengandungi untuk melaksanakan Senarai generik). 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