l'éditeur php Yuzai vous propose un article sur la façon d'attribuer ou de renvoyer un T universel soumis aux contraintes syndicales. Lors de l’écriture de code PHP, nous devons parfois définir un type de données, qui peut être une combinaison de plusieurs types différents. C'est le type d'union. Cependant, nous pouvons rencontrer une certaine confusion lorsque nous essayons d'attribuer ou de renvoyer un tel T générique contraint par l'union. Cet article vous donnera une réponse détaillée sur la façon de résoudre ce problème, vous permettant de mieux appliquer le T universel du type union.
En d'autres termes, comment implémenter une solution spécifique à un type pour différents types dans un ensemble de types d'union ?
Étant donné le code suivant...
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 }
Le compilateur affiche une erreur :
field.go:37:9: cannot use value (variable of type string) as type t in return statement
Existe-t-il un moyen de fournir des implémentations pour tous les fieldtype
possibles ?
J'aime...
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 }
Tous les conseils sont les bienvenus.
Cette erreur se produit car les opérations impliquant des paramètres de type (y compris l'affectation et le retour) doivent être valides pour tous les types de leur ensemble de types.
Si string | int
, il n'y a pas d'opération courante pour initialiser leurs valeurs à partir de chaînes.
Mais il vous reste encore quelques options :
Tapez allumaget
Vous utilisez un champ de type générique t
的字段,并临时将具体类型的值设置到 接口{}
/any
中。然后将接口键入断言回 t
以返回它。请注意,此断言未经检查,因此如果由于某种原因 ret
持有不属于 t
dans un commutateur de type et définissez temporairement la valeur du type spécifique dans le interface{}
/any
. Tapez ensuite à nouveau l'assertion d'interface dans
ret
contient quelque chose qui ne fait pas partie de l'ensemble de types *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
Vous pouvez simplifier davantage le code ci-dessus et vous débarrasser de l'interface vide. Dans ce cas, vous obtenez l'adresse d'une variable de type et ouvrez le type pointeur.
: 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 }
en interface{}
/any
pour l'utiliser dans un commutateur de type. Vous ne pouvez pas taper switch directement sur os.lookupenv
.
Aire de jeux avec
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!