Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menetapkan atau mengembalikan subjek T generik kepada kesatuan?

Bagaimana untuk menetapkan atau mengembalikan subjek T generik kepada kesatuan?

WBOY
WBOYke hadapan
2024-02-09 20:30:19793semak imbas

如何分配或返回受联合约束的通用 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
}

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.

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
}
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
}

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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam