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.
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 }
Compiler zeigt Fehler:
field.go:37:9: cannot use value (variable of type string) as type t in return statement
Gibt es eine Möglichkeit, Implementierungen für alle möglichen fieldtype
s 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 }
Alle Tipps willkommen.
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“ eint
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
ret
aus irgendeinem Grund etwas enthält, das nicht Teil des Typsatzes *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 }
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.
: 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 }
-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
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!