Wie kann man einer Union ein generisches T-Subjekt zuweisen oder es zurückgeben?

WBOY
Freigeben: 2024-02-09 20:30:19
nach vorne
848 Leute haben es durchsucht

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

php-Editor Yuzai bringt Ihnen einen Artikel darüber, wie Sie ein universelles T unter Gewerkschaftsbeschränkungen zuweisen oder zurückgeben. Beim Schreiben von PHP-Code müssen wir manchmal einen Datentyp definieren, der eine Kombination aus mehreren verschiedenen Typen sein kann. Dies ist der Union-Typ. Allerdings kann es zu Verwirrung kommen, wenn wir versuchen, ein solches gewerkschaftsbeschränktes generisches T zuzuweisen oder zurückzugeben. In diesem Artikel erhalten Sie eine detaillierte Antwort, wie Sie mit diesem Problem umgehen können, damit Sie das allgemeine T des Union-Typs besser anwenden können.

Frageninhalt

Mit anderen Worten: Wie implementiert man eine typspezifische Lösung für verschiedene Typen in einem Union-Typ-Set?

Angesichts des folgenden Codes...

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
}
Nach dem Login kopieren

Compiler zeigt Fehler:

field.go:37:9: cannot use value (variable of type string) as type t in return statement
Nach dem Login kopieren

Gibt es eine Möglichkeit, Implementierungen für alle möglichen fieldtypes bereitzustellen?

Gefällt mir...

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
}
Nach dem Login kopieren

Alle Tipps willkommen.

Problemumgehung

Dieser Fehler tritt auf, weil Vorgänge mit Typparametern (einschließlich Zuweisung und Rückgabe) für alle Typen in ihrem Typsatz gültig sein müssen. Wenn string | int, gibt es keine allgemeine Operation zum Initialisieren ihrer Werte aus Zeichenfolgen.

Aber Sie haben noch ein paar Möglichkeiten:

Geben Sie „Einschalten“ ein

t

Sie verwenden ein Feld eines generischen Typs t 的字段,并临时将具体类型的值设置到 接口{}/any 中。然后将接口键入断言回 t 以返回它。请注意,此断言未经检查,因此如果由于某种原因 ret 持有不属于 t in einem Typschalter und legen vorübergehend den Wert des spezifischen Typs in der Schnittstelle{}/any fest. Geben Sie dann die Schnittstellenzusicherung wieder in

ein, um sie zurückzugeben. Beachten Sie, dass diese Behauptung nicht aktiviert ist. Wenn also ret aus irgendeinem Grund etwas enthält, das nicht Teil des Typsatzes

ist, geraten Sie möglicherweise in Panik. Natürlich können Sie es mit „comma -ok“ überprüfen, aber es ist immer noch eine Laufzeitaussage: *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
}
Nach dem Login kopieren
Geben Sie „Einschalten“ ein

t Sie können den obigen Code weiter vereinfachen und die leere Schnittstelle entfernen. In diesem Fall erhalten Sie die Adresse einer Variablen vom Typ und öffnen den Zeigertyp.

Dies wird zur Kompilierungszeit vollständig typgeprüft

: 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
}
Nach dem Login kopieren
Beachten Sie, dass Sie in beiden Fällen den

-Wert in interface{}/any umwandeln müssen, um ihn in einem Typwechsel zu verwenden. Sie können „switch“ nicht direkt eintippen os.lookupenv. Spielplatz mit simulierter

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

Das obige ist der detaillierte Inhalt vonWie kann man einer Union ein generisches T-Subjekt zuweisen oder es zurückgeben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!