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

WBOY
Lepaskan: 2024-02-06 08:15:04
ke hadapan
572 orang telah melayarinya

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...
Salin selepas log masuk

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
}
Salin selepas log masuk

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

sebagai
type List[T comparable] []T
Salin selepas log masuk

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
}
Salin selepas log masuk

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
}
Salin selepas log masuk

Untuk jenis yang serupa, anda boleh memberikan nilai lalai:

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

Jadi perkara di atas menjadi

func main() {
    list := List[int]([]int{1,2,3})
    fmt.Println(list.Contains(2, Eq[int]) // true
}
Salin selepas log masuk
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!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan