Rumah > pembangunan bahagian belakang > Golang > Senarai struktur/antara muka biasa di Golang

Senarai struktur/antara muka biasa di Golang

WBOY
Lepaskan: 2024-02-13 17:30:11
ke hadapan
560 orang telah melayarinya

Golang 中的通用结构/接口列表

editor php Baicao akan memperkenalkan anda kepada senarai struktur/antara muka biasa di Golang dalam artikel ini. Golang ialah bahasa pengaturcaraan sumber terbuka yang mudah dipelajari, cekap dan boleh dipercayai Ia digunakan secara meluas dalam pengaturcaraan rangkaian, pengkomputeran awan dan bidang lain. Di Golang, struktur dan antara muka biasa ialah konsep yang sangat penting yang boleh membantu kami mencapai kebolehgunaan semula dan kebolehskalaan kod. Melalui pengenalan artikel ini, saya percaya pembaca boleh lebih memahami dan menggunakan struktur dan antara muka biasa di Golang dan meningkatkan kemahiran pengaturcaraan mereka.

Kandungan soalan

Adakah terdapat cara untuk mendapatkan senarai struktur/antara muka biasa?

Ini yang saya mahu capai.

<code>package main

type List[T any] struct {
    Elements []T
}

func (f *List[T]) Add(el T) {
    f.Elements = append(f.Elements, el)
}

type ListInterface[T any] interface {
    Add(el T)
}

func main() {
    listOfLists := make([]ListInterface[any], 0)
    listOfLists = append(listOfLists, &List[int]{})
}
</code>
Salin selepas log masuk

Ini adalah kesilapan yang saya dapat.

cannot use &List[int]{} (value of type *List[int]) as ListInterface[any] value in argument to append: *List[int] does not implement ListInterface[any] (wrong type for method Add)
    have Add(int)
    want Add(any)
Salin selepas log masuk

Jadi, jika saya faham betul, in go any adalah jenisnya sendiri. Ia bukan sinonim untuk "apa sahaja jenis yang dikehendaki oleh masa jalan". Soalan saya, adakah mungkin untuk melakukan sesuatu seperti ini?

Penyelesaian

Apa yang anda cuba lakukan di sini menunjukkan bahawa anda mengharapkan generik go mampu memadam jenis (sama seperti generik Java). Tetapi itu tidak berlaku.

Anda ada List[int],这意味着它的 Add kaedah seperti ini:

func (l *List) Add(el int) {
    l.Elements = append(l.Elements, el)
}
Salin selepas log masuk

Kemudian cuba tambahkannya pada kepingan objek yang melaksanakan antara muka itu:

Add(v any)
Salin selepas log masuk

Sekarang, anda mungkin berfikir bahawa int boleh digunakan sebagai int 可以用作 any, anda betul, boleh, tetapi apabila anda melihat:

var s []ListInterface[any]
Salin selepas log masuk

Anda mengatakan bahawa semua elemen dalam kepingan tersebut akan mempunyai kaedah Tambah yang mengambil parameter jenis Add 方法,该方法采用 any jadi ini bermakna:

s[0].Add("foo")
s[1].Add(123)
Salin selepas log masuk

Panggilan hendaklah sentiasa sah. Jika s[0] 的类型为 List[int] (如您的代码片段中的情况),则这不成立。您将尝试将字符串附加到 Elements ,其类型为 []int.

Ada pepatah mengatakan pembalikan harus dibenarkan:

s := []ListInterface[int]{}
s = append(s, &List[any]{})
Salin selepas log masuk

Nampaknya List[any] 将接受 int parameter, tetapi ini juga tidak dibenarkan. Ini boleh berguna dalam beberapa kes, tetapi dalam banyak kes ini boleh menjadi masalah.

Pada asasnya, generik dalam Go ialah sesuatu yang dikendalikan pada masa penyusunan. Apabila anda mencipta List[int] 时,编译器将创建一个类似 List_int 的类型,并在该类型上实现 Add(el int) 方法,与您最终使用的任何其他 List 类型相同。这些类型都不会具有 Add(any) 方法,除非您创建 List[any]. Fikirkannya sebagai penjanaan kod plat dandang dibantu pengkompil. Bukan pemadaman jenis masa jalan.

Keputusan: List[int]List[any] adalah jenis yang berbeza dan oleh itu tidak boleh duduk bersebelahan dalam kepingan seolah-olah mereka adalah jenis yang sama. Jika anda mahu dapat melakukan apa yang anda mahu, anda boleh lakukan ini:

func (l *List[T]) AddAny(v any) {
    tv, ok := v.(T)
    if !ok {
        return // or return an error
    }
    l.Add(tv)
}
Salin selepas log masuk

Ambil pendekatan nilai any, menggunakan penegasan jenis untuk melihat sama ada nilai yang diberikan serasi dengan jenis asas senarai, dan tambahkannya jika itu yang berlaku. Anda kemudian boleh menambahnya ke dalam satu kepingan seperti ini:

type Lists interface {
    AddAny(any)
}

s := []Lists{}
s = append(s, &List[int]{}, &List[string]{})
s[0].AddAny(123) // will work
s[0].AddAny("foo") // will not, with the current code this will silently fail
s[1].AddAny("foo") // works fine
s[1].AddAny(123) // silently fails
Salin selepas log masuk

Tetapi pada hakikatnya, apabila anda melakukan sesuatu seperti ini, kod itu hanya menjerit masalah X-Y, anda cuba menggunakan Y (generik) untuk menyelesaikan masalah anda, sedangkan masalah sebenar ialah X: apakah cara terbaik untuk menyelesaikan masalah?

Atas ialah kandungan terperinci Senarai struktur/antara muka biasa di Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
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