J'ai ce qui suit:
let mut my_number = 32.90;
Comment imprimer le type de my_number
?
Utilisation type
et type_of
n'a pas fonctionné. Existe-t-il une autre façon d'imprimer le type du numéro?
Si vous souhaitez simplement découvrir le type d'une variable et êtes prêt à le faire lors de la compilation, vous pouvez provoquer une erreur et demander au compilateur de la récupérer.
Par exemple, définissez la variable sur un type qui ne fonctionne pas :
let mut my_number: () = 32.90;
// let () = x; would work too
error[E0308]: mismatched types
--> src/main.rs:2:29
|
2 | let mut my_number: () = 32.90;
| ^^^^^ expected (), found floating-point number
|
= note: expected type `()`
found type `{float}`
Ou appelez une méthode non valide :
let mut my_number = 32.90;
my_number.what_is_this();
error[E0599]: no method named `what_is_this` found for type `{float}` in the current scope
--> src/main.rs:3:15
|
3 | my_number.what_is_this();
| ^^^^^^^^^^^^
Ou accédez à un champ invalide :
let mut my_number = 32.90;
my_number.what_is_this
error[E0610]: `{float}` is a primitive type and therefore doesn't have fields
--> src/main.rs:3:15
|
3 | my_number.what_is_this
| ^^^^^^^^^^^^
Ceux-ci révèlent le type, qui dans ce cas n'est en fait pas entièrement résolu. Cela s'appelle «variable à virgule flottante» dans le premier exemple et « {float}
» dans les trois exemples; il s'agit d'un type partiellement résolu qui pourrait finir f32
ou f64
, selon la façon dont vous l'utilisez. « {float}
» Est pas un nom de type juridique, il est un espace réservé qui signifie « Je suis sûr que pas tout à fait ce que cela est », mais il est un nombre à virgule flottante. Dans le cas des variables à virgule flottante, si vous ne la contraignez pas, elle sera par défaut f64
¹. (Un littéral entier non qualifié sera défini par défaut sur i32
.)
Voir également:
¹ Il peut encore y avoir des moyens de dérouter le compilateur pour qu'il ne puisse pas décider entre f32
et f64
; Je ne suis pas sûr. Auparavant, c'était aussi simple que cela 32.90.eq(&32.90)
, mais cela traite à la fois comme f64
maintenant et se déroule joyeusement, donc je ne sais pas.
:?
est depuis longtemps mis en œuvre manuellement. Mais plus important encore, l'std::fmt::Debug
implémentation (car c'est ce qui est:?
utilisé) pour les types de nombres n'inclut plus de suffixe pour indiquer de quel type il s'agit.ImageBuffer<_, Vec<_>>
qui ne m'aide pas beaucoup lorsque j'essaie d'écrire une fonction qui prend l'une de ces choses comme paramètre. Et cela se produit dans du code qui autrement se compile jusqu'à ce que j'ajoute le:()
. N'y a-t-il pas de meilleur moyen?Il existe une fonction instable
std::intrinsics::type_name
qui peut vous donner le nom d'un type, bien que vous deviez utiliser une version nocturne de Rust (cela ne fonctionnera probablement jamais dans Rust stable). Voici un exemple:la source
#![feature(core_intrinsics)]
print_type_of
prend des références (&T
), pas des valeurs (T
), vous devez donc passer&&str
plutôt que&str
; c'estprint_type_of(&"foo")
plutôt queprint_type_of("foo")
.std::any::type_name
est stable depuis la rouille 1.38: stackoverflow.com/a/58119924Vous pouvez utiliser la
std::any::type_name
fonction. Cela n'a pas besoin d'un compilateur nocturne ou d'une caisse externe, et les résultats sont tout à fait corrects:Attention: comme indiqué dans la documentation, ces informations ne doivent être utilisées qu'à des fins de débogage:
Si vous voulez que votre représentation de type reste la même entre les versions du compilateur, vous devez utiliser un trait, comme dans la réponse du phicr .
la source
Si vous connaissez tous les types au préalable, vous pouvez utiliser des traits pour ajouter une
type_of
méthode:Pas d'intrication ou rien, donc bien que plus limité,
c'est la seule solution ici qui vous donne une chaîne et est stable.(voir la réponse du français Boiethios ) Cependant, c'est très laborieux et ne tient pas compte des paramètres de type, donc nous pourrions ...Utilisons-le:
production:
Aire de jeux de rouille
la source
UPD Ce qui suit ne fonctionne plus. Vérifiez la réponse de Shubham pour correction.
Découvrez
std::intrinsics::get_tydesc<T>()
. Il est actuellement dans un état "expérimental", mais ce n'est pas grave si vous piratez simplement le système de type.Découvrez l'exemple suivant:
C'est ce qui est utilisé en interne pour implémenter le célèbre
{:?}
formateur.la source
** MISE À JOUR ** Cela n'a pas été vérifié pour fonctionner à tout moment récemment.
J'ai mis en place une petite caisse pour le faire en fonction de la réponse de vbo. Il vous donne une macro pour retourner ou imprimer le type.
Mettez ceci dans votre fichier Cargo.toml:
Ensuite, vous pouvez l'utiliser comme ceci:
la source
#![feature]
ne peut pas être utilisé sur le canal de sortie stable»Vous pouvez également utiliser l'approche simple consistant à utiliser la variable dans
println!("{:?}", var)
. SiDebug
n'est pas implémenté pour le type, vous pouvez voir le type dans le message d'erreur du compilateur:( parc )
C'est sale mais ça marche.
la source
Debug
n'est pas implémenté - c'est un cas assez improbable cependant. L'une des premières choses que vous devriez faire pour la plupart des structures est d'ajouter#[derive(Debug)]
. Je pense que les moments où vous ne voulez pasDebug
sont très petits.println!("{:?}", unknown_var);
?? Est-ce une interpolation de chaîne mais pourquoi l':?
intérieur des accolades? @DenisKolodinDebug
car il n'est pas implémenté, mais vous pouvez également l'utiliser{}
.Il y a une réponse @ChrisMorgan pour obtenir le type approximatif ("float") dans la rouille stable et il y a une réponse @ShubhamJain pour obtenir le type précis ("f64") grâce à la fonction instable dans la rouille nocturne.
Maintenant, voici un moyen d'obtenir un type précis (c'est-à-dire de choisir entre f32 et f64) dans la rouille stable:
résulte en
Mettre à jour
La variation du turbofish
est légèrement plus court mais un peu moins lisible.
la source
float
, dire entref32
etf64
peut être accompli avecstd::mem::size_of_val(&a)
D'autres réponses ne fonctionnent pas, mais je trouve que le typename fonctionne caisse.
Créez un nouveau projet:
Modifier le Cargo.toml
Modifiez votre code source
La sortie est:
la source
typename
ne fonctionne pas avec des variables sans type explicite dans la déclaration. L'exécuter avecmy_number
la question donne l'erreur suivante "impossible d'appeler la méthodetype_name_of
sur un type numérique ambigu{float}
. Aide: vous devez spécifier un type pour cette liaison, commef32
"0.65
et il fonctionne bien:type of c 0.65 0.65 is f64
. voici ma version:rustc 1.38.0-nightly (69656fa4c 2019-07-13)
Si vous voulez juste connaître le type de votre variable pendant le développement interactif, je vous recommande fortement d'utiliser rls (rust language server) dans votre éditeur ou ide. Vous pouvez ensuite simplement activer ou basculer de manière permanente la capacité de survol et placer simplement votre curseur sur la variable. Une petite boîte de dialogue devrait fournir des informations sur la variable, y compris le type.
la source