Kekangan taip Go yang menerangkan kelakuan struktur boleh ubah

WBOY
Lepaskan: 2024-02-08 21:15:10
ke hadapan
664 orang telah melayarinya

描述可变结构行为的 Go 类型约束

editor php Xinyi hari ini memperkenalkan kepada anda kekangan jenis Go yang menerangkan tingkah laku struktur berubah. Dalam bahasa Go, kita boleh menggunakan jenis antara muka untuk menentukan set kaedah dan mengehadkan jenis parameter masuk melalui kekangan jenis. Kaedah ini boleh melakukan semakan jenis pada masa penyusunan untuk memastikan keselamatan dan kebolehpercayaan kod. Dengan menggunakan jenis antara muka dan kekangan jenis secara rasional, kami boleh mencapai fleksibiliti dan skalabiliti kod, serta meningkatkan kebolehselenggaraan dan kebolehbacaan program. Seterusnya, mari kita lihat dengan lebih dekat cara menggunakan kekangan jenis Go untuk menerangkan tingkah laku struct boleh ubah.

Kandungan soalan

Saya ingin mentakrifkan fungsi generik di mana kekangan jenis menerangkan tingkah laku struktur boleh ubah.

Apa yang saya maksudkan dengan "tingkah laku boleh ubah" ialah antara muka seperti ini:

type Unmarshaler interface {
    Unmarshal(data []byte) error
}
Salin selepas log masuk

...Pelaksanaannya kelihatan seperti ini:

type Foo struct {
    Content string
}

func (f *Foo) Unmarshal(data []byte) error {
    f.Content = string(data)
    return nil
}
Salin selepas log masuk

Panggil kaedah antara muka akan mengubah struktur .

Apa yang saya mahu lakukan ialah mentakrifkan fungsi generik di mana kekangan jenis ialah antara muka di atas. Fungsi generik bertanggungjawab untuk memulakan contoh jenis konkrit, kemudian mengubahnya menggunakan kaedah antara muka dan mengembalikannya.

func Unmarshal[T Unmarshaler](data []byte) (T, error) {
    var m T
    return m, m.Unmarshal(data)
}
Salin selepas log masuk

Jadi saya mahu boleh memanggil fungsi generik ini menggunakan jenis Foo.

func main() {
    foo, err := Unmarshal[*Foo]([]byte("hello"))
    if err == nil {
        log.Println(foo.Content) // hello
    } else {
        log.Fatal(err)
    }
}
Salin selepas log masuk

Saya perlu lulus *Foo 作为类型参数,因为只有指向 Foo 的指针才实现 Unmarshaler 接口。但是,当 Foo 的 Unmarshal 方法收到 fnil 值时,就会出现恐慌。这对我来说都是有意义的,因为 var m T 将使指向 Foo nilai penunjuk sifar, iaitu sifar. Tetapi saya tidak pasti sama ada saya telah menemui jalan buntu?

https://go.dev/play/p/H5s59NWNiDA

Sebaik-baiknya saya boleh menerangkannya, saya menghadapi masalah ini apabila kekangan jenis saya menerangkan beberapa kelakuan struct boleh ubah dan fungsi generik saya ingin memulakan dan kemudian mengubah instance struct. Adakah ini mungkin? Adakah terdapat cara yang lebih baik untuk membina ini?

Penyelesaian

Masalah utama ialah mencipta nilai untuk jenis tertentu T 创建有用的值。有几种方法可以做到这一点: m := make(T) (地图和频道)等。您可以使用 reflect pakej, tetapi lebih mudah untuk membiarkan pemanggil melepasi nilai sebagai parameter.

func Unmarshal[T Unmarshaler](m T, data []byte) (T, error) {
    return m, m.Unmarshal(data)
}
Salin selepas log masuk

Panggil fungsi seperti ini:

foo, err := Unmarshal(&Foo{}, []byte("hello"))
Salin selepas log masuk

https://www.php.cn/link/8eb51d0a68e9373df41f88e5b551d4a3

Atas ialah kandungan terperinci Kekangan taip Go yang menerangkan kelakuan struktur boleh ubah. 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