editor php Yuzai membawakan anda artikel tentang cara menetapkan atau mengembalikan T universal tertakluk kepada kekangan kesatuan. Apabila menulis kod PHP, kadangkala kita perlu menentukan jenis data, yang boleh menjadi gabungan pelbagai jenis. Ini adalah jenis kesatuan. Walau bagaimanapun, kami mungkin mengalami kekeliruan apabila kami cuba memberikan atau mengembalikan T generik yang dikekang oleh kesatuan sebegitu. Artikel ini akan memberi anda jawapan terperinci tentang cara menangani masalah ini, membolehkan anda menggunakan T am jenis kesatuan dengan lebih baik.
Dalam erti kata lain, bagaimana untuk melaksanakan penyelesaian khusus jenis untuk jenis yang berbeza dalam set jenis kesatuan?
Diberi kod berikut...
type fieldtype interface { string | int } type field[t fieldtype] struct { name string defaultvalue t } func newfield[t fieldtype](name string, defaultvalue t) *field[t] { return &field[t]{ name: name, defaultvalue: defaultvalue, } } func (f *field[t]) name() string { return f.name } func (f *field[t]) get() (t, error) { value, ok := os.lookupenv(f.name) if !ok { return f.defaultvalue, nil } return value, nil }
Pengkompil menunjukkan ralat:
field.go:37:9: cannot use value (variable of type string) as type t in return statement
Adakah terdapat cara untuk menyediakan pelaksanaan untuk semua fieldtype
yang mungkin?
Suka...
func (f *Field[string]) Get() (string, error) { value, ok := os.LookupEnv(f.name) if !ok { return f.defaultValue, nil } return value, nil } func (f *Field[int]) Get() (int, error) { raw, ok := os.LookupEnv(f.name) if !ok { return f.defaultValue, nil } value, err := strconv.ParseInt(raw, 10, 64) if err != nil { return *new(T), err } return int(value), nil }
Sebarang petua dialu-alukan.
Ralat ini berlaku kerana operasi yang melibatkan parameter jenis (termasuk tugasan dan pemulangan) mesti sah untuk semua jenis dalam set jenisnya.
Jika string | int
, tiada operasi biasa untuk memulakan nilainya daripada rentetan.
Tetapi anda masih mempunyai beberapa pilihan:
Taip menghidupkant
Anda menggunakan medan jenis generik t
的字段,并临时将具体类型的值设置到 接口{}
/any
中。然后将接口键入断言回 t
以返回它。请注意,此断言未经检查,因此如果由于某种原因 ret
持有不属于 t
dalam suis jenis dan tetapkan sementara nilai jenis tertentu ke dalam antara muka{}
/mana-mana
. Kemudian taip penegasan antara muka kembali ke
ret
memegang sesuatu yang bukan sebahagian daripada set jenis *t
func (f *field[t]) get() (t, error) { value, ok := os.lookupenv(f.name) if !ok { return f.defaultvalue, nil } var ret any switch any(f.defaultvalue).(type) { case string: ret = value case int: // don't actually ignore errors i, _ := strconv.parseint(value, 10, 64) ret = int(i) } return ret.(t), nil }
t
Anda boleh memudahkan lagi kod di atas dan menyingkirkan antara muka kosong. Dalam kes ini, anda mendapat alamat pembolehubah jenis dan buka jenis penunjuk.
: t
值转换为 interface{}
/any
才能在类型开关中使用它。您无法直接在 t
func (f *Field[T]) Get() (T, error) { value, ok := env[f.name] if !ok { return f.defaultValue, nil } var ret T switch p := any(&ret).(type) { case *string: *p = value case *int: i, _ := strconv.ParseInt(value, 10, 64) *p = int(i) } // ret has the zero value if no case matches return ret, nil }
ke antara muka{}
/mana-mana
untuk menggunakannya dalam suis jenis. Anda tidak boleh menaip suis terus hidupkan os.lookupenv
.
Taman permainan dengan simulasi
Atas ialah kandungan terperinci Bagaimana untuk menetapkan atau mengembalikan subjek T generik kepada kesatuan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!