Heim  >  Artikel  >  Backend-Entwicklung  >  So konvertieren Sie eine Schnittstelle mithilfe von Generika in einen angegebenen Typ

So konvertieren Sie eine Schnittstelle mithilfe von Generika in einen angegebenen Typ

WBOY
WBOYnach vorne
2024-02-06 08:25:111002Durchsuche

So konvertieren Sie eine Schnittstelle mithilfe von Generika in einen angegebenen Typ

Frageninhalt

Es gibt eine Schnittstellendeklaration und viele Strukturen, die diese implementieren

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

beinhaltet auch datac,d,e...

Ich werde diese datax 结构实例存储到 type dataslice []datainterface

stellen

Wenn ich jetzt datax will, kann ich das tun:

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

Anscheinend gibt es hier eine Menge doppelten Code:

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

Also dachte ich, ich könnte Generika verwenden, um dieses Problem zu lösen, und habe dann diese Funktion definiert:

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

Aber es ist ein Fehler aufgetreten: impossible 类型断言:'*t' 未实现 'datainterface

Ich möchte also wissen, ob das wirklich unmöglich ist? Oder geht das auch anders?


Richtige Antwort


Sie sollten in der Lage sein, den folgenden Code zu verwenden, um Ihre Anforderungen zu erfüllen:

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

Zuerst habe ich den Code vereinfacht, indem ich nur berücksichtigt habe, dass er erfolgreich funktioniert und Sie alle Informationen wie die Struktur erhalten. dataadatab 结构。然后,我将指针接收器更改为值接收器,因为您不会更改传递给方法的实际实例的状态。由于此更改,getdatax

Wenn dies Ihr Problem löst oder Sie etwas anderes benötigen, lassen Sie es mich bitte wissen, vielen Dank!

Das obige ist der detaillierte Inhalt vonSo konvertieren Sie eine Schnittstelle mithilfe von Generika in einen angegebenen Typ. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen