Ich habe folgendes:
let mut my_number = 32.90;
Wie drucke ich den Typ von my_number
?
Verwenden type
und type_of
hat nicht funktioniert. Gibt es eine andere Möglichkeit, den Typ der Nummer auszudrucken?
Wenn Sie lediglich den Typ einer Variablen herausfinden möchten und dies zur Kompilierungszeit tun möchten , können Sie einen Fehler verursachen und den Compiler veranlassen, ihn abzurufen.
Zum Beispiel setzen Sie die Variable auf eine Art , die nicht funktioniert :
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}`
Oder rufen Sie eine ungültige Methode auf :
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();
| ^^^^^^^^^^^^
Oder greifen Sie auf ein ungültiges Feld zu :
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
| ^^^^^^^^^^^^
Diese zeigen den Typ, der in diesem Fall tatsächlich nicht vollständig aufgelöst ist. Im ersten Beispiel heißt es "Gleitkommavariable" und {float}
in allen drei Beispielen " ". Dies ist ein teilweise aufgelöster Typ, der enden kann f32
oder f64
je nachdem, wie Sie ihn verwenden. " {float}
" Ist kein legaler Typname, sondern ein Platzhalter, der "Ich bin mir nicht ganz sicher, was das ist" bedeutet, aber es ist eine Gleitkommazahl. Wenn Sie bei Gleitkommavariablen diese nicht einschränken, wird standardmäßig f64
¹ verwendet. (Ein unqualifiziertes Integer-Literal wird standardmäßig verwendet i32
.)
Siehe auch:
¹ Möglicherweise gibt es immer noch Möglichkeiten, den Compiler zu verwirren, sodass er sich nicht zwischen f32
und entscheiden kann f64
. Ich bin mir nicht sicher. Früher war es so einfach wie jetzt 32.90.eq(&32.90)
, aber das behandelt sowohl f64
jetzt als auch tuckert glücklich mit, also weiß ich es nicht.
:?
wurde schon lange manuell implementiert. Noch wichtiger ist jedoch, dass diestd::fmt::Debug
Implementierung (für die dies:?
verwendet wird) für Zahlentypen kein Suffix mehr enthält, das angibt, um welchen Typ es sich handelt.ImageBuffer<_, Vec<_>>
nicht sehr hilft, wenn ich versuche, eine Funktion zu schreiben, die eines dieser Dinge als Parameter verwendet. Und dies geschieht in Code, der ansonsten kompiliert wird, bis ich den hinzufüge:()
. Gibt es keinen besseren Weg?Es gibt eine instabile Funktion
std::intrinsics::type_name
, mit der Sie den Namen eines Typs erhalten können, obwohl Sie einen nächtlichen Build von Rust verwenden müssen (dies wird wahrscheinlich nie in stabilem Rust funktionieren). Hier ist ein Beispiel:quelle
#![feature(core_intrinsics)]
print_type_of
nimmt Referenzen (&T
), nicht Werte (T
), also müssen Sie übergeben&&str
anstatt&str
; das heißt,print_type_of(&"foo")
eher alsprint_type_of("foo")
.std::any::type_name
ist stabil seit Rost 1.38: stackoverflow.com/a/58119924Sie können die
std::any::type_name
Funktion verwenden. Dies erfordert keinen nächtlichen Compiler oder eine externe Kiste, und die Ergebnisse sind ganz richtig:Seien Sie gewarnt: Wie in der Dokumentation angegeben, dürfen diese Informationen nur für Debug-Zwecke verwendet werden:
Wenn Sie möchten, dass Ihre Typdarstellung zwischen den Compilerversionen gleich bleibt, sollten Sie ein Merkmal verwenden, wie in der Antwort des Phicr .
quelle
Wenn Sie alle Typen im Voraus kennen, können Sie mithilfe von Merkmalen eine
type_of
Methode hinzufügen :Keine Feinheiten oder nichts, obwohl dies eingeschränkter ist, ist
dies die einzige Lösung hier, die Ihnen einen String gibt und stabil ist.(Siehe die Antwort von French Boiethios. ) Es ist jedoch sehr mühsam und berücksichtigt keine Typparameter, sodass wir ...Lass es uns benutzen:
Ausgabe:
Rostspielplatz
quelle
UPD Folgendes funktioniert nicht mehr. Überprüfen Sie Shubhams Antwort auf Korrektur.
Auschecken
std::intrinsics::get_tydesc<T>()
. Es befindet sich derzeit im "experimentellen" Zustand, aber es ist in Ordnung, wenn Sie nur das Typsystem hacken.Schauen Sie sich das folgende Beispiel an:
Dies wird intern verwendet , um den berühmten
{:?}
Formatierer zu implementieren .quelle
** UPDATE ** Es wurde in letzter Zeit nicht überprüft, ob dies funktioniert.
Ich habe eine kleine Kiste zusammengestellt, um dies basierend auf der Antwort von vbo zu tun. Sie erhalten ein Makro, mit dem Sie den Typ zurückgeben oder ausdrucken können.
Fügen Sie dies in Ihre Cargo.toml-Datei ein:
Dann können Sie es so verwenden:
quelle
#![feature]
darf nicht auf dem stabilen Release-Kanal verwendet werden`Sie können auch den einfachen Ansatz verwenden, die Variable in zu verwenden
println!("{:?}", var)
. WennDebug
für den Typ nicht implementiert, wird der Typ in der Fehlermeldung des Compilers angezeigt:( Laufstall )
Es ist schmutzig, aber es funktioniert.
quelle
Debug
nicht implementiert ist, ist dies jedoch ein ziemlich unwahrscheinlicher Fall. Eines der ersten Dinge, die Sie für die meisten Strukturen tun sollten, ist das Hinzufügen#[derive(Debug)]
. Ich denke, die Zeiten, in denen du nicht willst,Debug
sind sehr klein.println!("{:?}", unknown_var);
? Ist es eine String-Interpolation, aber warum das:?
Innere der geschweiften Klammern? @ DenisKolodinDebug
weil es nicht implementiert ist, aber Sie können es auch verwenden{}
.Es gibt eine @ ChrisMorgan- Antwort , um den ungefähren Typ ("float") in stabilem Rost zu erhalten, und es gibt eine @ ShubhamJain- Antwort , um einen genauen Typ ("f64") durch instabile Funktion in nächtlichem Rost zu erhalten.
Hier ist eine Möglichkeit, wie man einen präzisen Typ (dh zwischen f32 und f64 entscheiden) für stabilen Rost erhalten kann:
führt zu
Aktualisieren
Die Turbofisch-Variante
ist etwas kürzer aber etwas weniger lesbar.
quelle
float
, zu sagen zwischenf32
undf64
erreicht werden kann , mitstd::mem::size_of_val(&a)
Einige andere Antworten funktionieren nicht, aber ich finde, dass die Typennamen- Kiste funktioniert.
Erstellen Sie ein neues Projekt:
Ändern Sie die Cargo.toml
Ändern Sie Ihren Quellcode
Die Ausgabe ist:
quelle
typename
nicht mehr mit Variablen ohne expliziten Typ in der Deklaration. Wenn Sie es mitmy_number
der Frage ausführen, wird der folgende Fehlertype_name_of
{float}
f32
0.65
und es funktioniert gut :type of c 0.65 0.65 is f64
. Hier ist meine Version:rustc 1.38.0-nightly (69656fa4c 2019-07-13)
Wenn Sie nur den Typ Ihrer Variablen während der interaktiven Entwicklung kennen möchten, würde ich die Verwendung von rls ( Rust Language Server) in Ihrem Editor oder Ihrer Idee sehr empfehlen . Sie können dann einfach die Schwebefähigkeit dauerhaft aktivieren oder umschalten und den Cursor einfach über die Variable bewegen. In einem kleinen Dialogfeld sollten Informationen zur Variablen einschließlich des Typs angezeigt werden.
quelle