Comment convertir une interface{} qui est vraiment une tranche de types dont le genre est reflect.Int32 en tranche de int32 ?
J'ai ce qui suit:
type Int32A int32
type Int32B int32
et souhaite implémenter une fonction qui peut accepter n'importe quelle tranche de types dont le type est reflect.Int32
et le convertir en []int32
. Par example:
func ConvertTypeSliceToInt32Slice(es «es-type») []int32 {
result:= make([]int32, len(es))
for i:= 0; i < len(result); i++ {
result[i] = es[i].(int32)
}
return result
}
func caller() {
Int32as:= Int32A{1, 2}
Int32bs:= Int32B{3, 5}
int32as:= ConvertTypeSliceToInt32Slice(Int32as)
int32bs:= ConvertTypeSliceToInt32Slice(Int32bs)
}
Comment cela peut-il être fait avec n'importe quelle définition de type arbitraire dont le genre est reflect.Int32
? (Contexte : cette fonction sera utilisée pour convertir des tranches de proto
enum
s ; c'est-à-dire que l'ensemble complet des types est inconnu et illimité, il switch
n'est donc pas possible d'effectuer un a sur chaque type).
De plus, j'utilise 1.17
donc je ne peux pas utiliser de types paramétrés (alias modèles).
Une tentative qui ne fonctionne pas (ça panique à is.([]interface{})
):
func ConvertTypeSliceToInt32Slice(is interface{}) []int32 {
es:= is.([]interface{})
result:= make([]int32, len(es))
for i:= 0; i < len(result); i++ {
result[i] = es[i].(int32)
}
return result
}
Solution du problème
int32
dans ce cas est un "type sous-jacent", et ~
dans une déclaration de paramètre de type est la façon dont vous spécifiez une contrainte à un type sous-jacent.
Par exemple : https://go.dev/play/p/8-WAu9KlXl5
func ConvertTypeSliceToInt32Slice[T ~int32](es []T) []int32 {
result:= make([]int32, len(es))
for i:= 0; i < len(result); i++ {
result[i] = int32(es[i])
}
return result
}
Si vous avez besoin d'utiliser la réflexion, vous pouvez convertir le type de chaque élément avant de l'ajouter à la tranche finale :
func ConvertTypeSliceToInt32Slice(es interface{}) []int32 {
v:= reflect.ValueOf(es)
int32ty:= reflect.TypeOf(int32(0))
result:= make([]int32, v.Len())
for i:= 0; i < v.Len(); i++ {
result[i] = v.Index(i).Convert(int32ty).Interface().(int32)
}
return result
}
Et si vous devez vous assurer que d'autres types numériques convertibles ne sont pas convertis, vous pouvez comparer le type d'élément et la panique ou l'erreur si nécessaire :
if v.Type().Elem().Kind()!= reflect.Int32 {
...
Commentaires
Enregistrer un commentaire