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
WBOYke hadapan
2024-02-06 08:25:111031semak imbas

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

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() .....

Nampaknya terdapat banyak kod pendua di sini:

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

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

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

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!

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