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.Int32et 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 enums ; c'est-à-dire que l'ensemble complet des types est inconnu et illimité, il switchn'est donc pas possible d'effectuer un a sur chaque type).

De plus, j'utilise 1.17donc 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

int32dans 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

Posts les plus consultés de ce blog

Comment signer la connexion OKEx API version 5 avec websockets ?

La fonction GCP Cloud pour écrire des données dans BigQuery s'exécute avec succès, mais les données n'apparaissent pas dans la table BigQuery

Le shell POSIX (sh) redirige stderr vers stdout et capture stderr et stdout dans des variables