Rumah > pembangunan bahagian belakang > Golang > Bagaimana untuk menukar antara muka kepada jenis yang ditentukan menggunakan generik

Bagaimana untuk menukar antara muka kepada jenis yang ditentukan menggunakan generik

WBOY
Lepaskan: 2024-02-06 08:25:11
ke hadapan
1045 orang telah melayarinya

Bagaimana untuk menukar antara muka kepada jenis yang ditentukan menggunakan generik

Kandungan soalan

Terdapat pengisytiharan antara muka dan banyak struktur yang melaksanakannya

type datainterface interface {
    get(string) string
}

type dataa struct {
    d map[string]string
}

func (d *dataa) get(key string) string {
    return d.d[key]
}

func (d *dataa) getid() string {
    return d.get("id")
}

type datab struct {
    d map[string]string
}

func (d *datab) get(key string) string {
    return d.d[key]
}

func (d *datab) getfile() string {
    return d.get("file")
}


type datac...
Salin selepas log masuk

juga termasuk datac,d,e...

Saya akan meletakkan ini datax 结构实例存储到 type dataslice []datainterface

Sekarang, jika saya ingin mendapatkan datax , saya boleh lakukan ini:

type dataslice []datainterface
func (d dataslice) geta() []*dataa {
    var ret []*dataa
    for _, di := range d {
        if v, ok := di.(*dataa); ok {
            ret = append(ret, v)
        }
    }
    return ret
}

func (d dataslice) getb() []*datab {
    var ret []*datab
    for _, di := range d {
        if v, ok := di.(*datab); ok {
            ret = append(ret, v)
        }
    }
    return ret
}

func (d dataslice) getc() .....
Salin selepas log masuk

Nampaknya terdapat banyak kod pendua di sini:

var ret []*datax
for _, di := range d {
    if v, ok := di.(*datax); ok {
        ret = append(ret, v)
    }
}
Salin selepas log masuk

Jadi saya fikir saya boleh menggunakan generik untuk menyelesaikan masalah ini, kemudian saya menentukan fungsi ini:

func GetDataX[T any] (d DataInterface) *T {
    return d.(*T)
}
Salin selepas log masuk

Tetapi ralat berlaku: impossible 类型断言:'*t' 未实现 'datainterface

Jadi saya ingin tahu adakah ini benar-benar mustahil? Atau bolehkah ia dilakukan dengan cara lain?


Jawapan betul


Anda sepatutnya boleh menggunakan kod berikut untuk memenuhi keperluan anda:

package main

import "fmt"

// interface
type DataInterface interface {
    Get(string) string
}

// struct implementing the interface
type DataA struct {
    d map[string]string
}

func (d DataA) Get(key string) string {
    return d.d[key]
}

type DataB struct {
    d map[string]string
}

func (d DataB) Get(key string) string {
    return d.d[key]
}

type DataSlice []DataInterface

func GetDataX[T any](d DataInterface) T {
    return d.(T)
}

func main() {
    a := DataA{map[string]string{"a": "1"}}
    b := DataB{map[string]string{"b": "2"}}

    ds := DataSlice{a, b}

    for _, v := range ds {
        if value, ok := v.(DataA); ok {
            fmt.Printf("A\t%q\n", GetDataX[DataA](value))
            continue
        }

        if value, ok := v.(DataB); ok {
            fmt.Printf("B\t%q\n", GetDataX[DataB](value))
            continue
        }

        // add unknown type handling logic here
    }
}
Salin selepas log masuk

Pertama sekali saya memudahkan kod memandangkan hanya dataadatab 结构。然后,我将指针接收器更改为值接收器,因为您不会更改传递给方法的实际实例的状态。由于此更改,getdatax ia berfungsi dengan jayanya dan anda mendapat semua maklumat seperti struktur.

Jika ini menyelesaikan masalah anda atau anda memerlukan sesuatu yang lain, sila beritahu saya, terima kasih!

Atas ialah kandungan terperinci Bagaimana untuk menukar antara muka kepada jenis yang ditentukan menggunakan generik. 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