Bagaimana untuk menetapkan atau mengembalikan subjek T generik kepada kesatuan?

WBOY
Lepaskan: 2024-02-09 20:30:19
ke hadapan
849 orang telah melayarinya

如何分配或返回受联合约束的通用 T?

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.

Kandungan soalan

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

Pengkompil menunjukkan ralat:

field.go:37:9: cannot use value (variable of type string) as type t in return statement
Salin selepas log masuk

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

Sebarang petua dialu-alukan.

Penyelesaian

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 menghidupkan

t

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

untuk mengembalikannya. Ambil perhatian bahawa pernyataan ini tidak ditandai, jadi jika atas sebab tertentu ret memegang sesuatu yang bukan sebahagian daripada set jenis

, anda mungkin panik. Sudah tentu anda boleh menyemaknya dengan koma -ok, tetapi ia masih merupakan penegasan masa jalan: *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
}
Salin selepas log masuk
Taip menghidupkan

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.

Ini ditaip sepenuhnya diperiksa pada masa penyusunan

: 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
}
Salin selepas log masuk
Perhatikan bahawa dalam kedua-dua kes anda mesti menghantar nilai

ke antara muka{}/mana-mana untuk menggunakannya dalam suis jenis. Anda tidak boleh menaip suis terus hidupkan os.lookupenv. Taman permainan dengan simulasi

peta: 🎜https://www.php.cn/link/498bce62bd2bda584246701fa0166482 🎜🎜

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!

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
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!