Mam następujące:
let mut my_number = 32.90;
Jak wydrukować typ my_number
?
Używanie type
i type_of
nie działało. Czy istnieje inny sposób wydrukowania typu numeru?
Jeśli chcesz się tylko dowiedzieć typ zmiennej i chcesz to zrobić w czasie kompilacji, możesz spowodować błąd i skłonić kompilator do jego pobrania.
Na przykład ustaw zmienną na typ, który nie działa :
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}`
Lub wywołaj nieprawidłową metodę :
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();
| ^^^^^^^^^^^^
Lub uzyskaj dostęp do nieprawidłowego pola :
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
| ^^^^^^^^^^^^
Ujawniają typ, który w tym przypadku nie jest w pełni rozwiązany. Nazywa się to „zmienną zmiennoprzecinkową” w pierwszym przykładzie i „ {float}
” we wszystkich trzech przykładach; jest to typ częściowo rozwiązany, który może się skończyć f32
lub f64
, w zależności od tego, jak go użyjesz. „ {float}
” Nie jest prawną nazwą typu, jest symbolem zastępczym oznaczającym „Nie jestem całkowicie pewien, co to jest”, ale jest liczbą zmiennoprzecinkową. W przypadku zmiennych zmiennoprzecinkowych, jeśli ich nie ograniczysz, domyślnie będzie to f64
¹. (Niekwalifikowany literał całkowity będzie domyślnie ustawiony na i32
.)
Zobacz też:
Đ nadal mogą być sposoby zaskakujący kompilator, tak, że nie można wybrać pomiędzy f32
i f64
; Nie jestem pewny. Kiedyś było tak proste 32.90.eq(&32.90)
, ale to traktuje zarówno f64
teraz, jak i szczęśliwie, więc nie wiem.
:?
już od dłuższego czasu jest wdrażany ręcznie. Ale co ważniejsze,std::fmt::Debug
implementacja (do tego właśnie:?
wykorzystuje) typów liczb nie zawiera już przyrostka wskazującego, jakiego typu ona jest.ImageBuffer<_, Vec<_>>
czegoś, co nie bardzo mi pomaga, gdy próbuję napisać funkcję, która przyjmuje jedną z tych rzeczy jako parametr. I dzieje się tak w kodzie, który inaczej się kompiluje, dopóki nie dodam:()
. Czy nie ma lepszego sposobu?Istnieje niestabilna funkcja,
std::intrinsics::type_name
która może dać ci nazwę typu, chociaż musisz użyć nocnej wersji Rdzy (jest mało prawdopodobne, aby działała w stabilnej Rust). Oto przykład:źródło
#![feature(core_intrinsics)]
print_type_of
przyjmuje referencje (&T
), a nie wartości (T
), więc musisz przekazać&&str
zamiast&str
; to znaczyprint_type_of(&"foo")
raczej niżprint_type_of("foo")
.std::any::type_name
jest stabilny od rdzy 1.38: stackoverflow.com/a/58119924Możesz użyć tej
std::any::type_name
funkcji. Nie wymaga to nocnego kompilatora ani zewnętrznej skrzynki, a wyniki są całkiem poprawne:Uwaga: jak wspomniano w dokumentacji, informacje te należy wykorzystywać wyłącznie w celu debugowania:
Jeśli chcesz, aby reprezentacja typu pozostała taka sama między wersjami kompilatora, powinieneś użyć cechy, takiej jak w odpowiedzi phicr .
źródło
Jeśli znasz wszystkie typy wcześniej, możesz użyć cech, aby dodać
type_of
metodę:Żadnych intrisk i nic, więc choć bardziej ograniczone,
jest to jedyne rozwiązanie, które daje ci ciąg i jest stabilne.(patrz odpowiedź francuskiego Boiethiosa ). Jest to jednak bardzo pracochłonne i nie uwzględnia parametrów typu, więc moglibyśmy ...Użyjmy tego:
wynik:
Plac zabaw dla rdzy
źródło
UPD Poniższe nie działa. Sprawdź odpowiedź Shubhama celu korekty.
Sprawdzić
std::intrinsics::get_tydesc<T>()
. W tej chwili jest w stanie „eksperymentalnym”, ale jest OK, jeśli tylko hakujesz wokół systemu typów.Sprawdź następujący przykład:
To jest używane wewnętrznie do implementacji słynnego
{:?}
formatera.źródło
** AKTUALIZACJA ** To nie zostało ostatnio zweryfikowane.
Złożyłem małą skrzynkę, aby to zrobić na podstawie odpowiedzi VBO. Daje makro do zwrócenia lub wydrukowania typu.
Umieść to w swoim pliku Cargo.toml:
Następnie możesz użyć go w następujący sposób:
źródło
#![feature]
nie można go używać w kanale stabilnego wydawania„Możesz także zastosować proste podejście do używania zmiennej w
println!("{:?}", var)
. JeśliDebug
nie jest zaimplementowany dla tego typu, możesz zobaczyć typ w komunikacie o błędzie kompilatora:( kojec )
Jest brudny, ale działa.
źródło
Debug
nie jest zaimplementowany - jest to jednak dość mało prawdopodobny przypadek. Jedną z pierwszych rzeczy, które powinieneś zrobić dla większości struktur, jest dodanie#[derive(Debug)]
. Myślę, że czasy, w których nie chcesz,Debug
są bardzo małe.println!("{:?}", unknown_var);
? Czy to interpolacja łańcuchowa, ale dlaczego w:?
nawiasach klamrowych? @DenisKolodinDebug
ponieważ nie jest zaimplementowane, ale możesz również użyć{}
.Istnieje odpowiedź @ChrisMorgan, aby uzyskać przybliżony typ („float”) w stabilnej rdzy, oraz odpowiedź @ShubhamJain, aby uzyskać dokładny typ („f64”) poprzez niestabilną funkcję w nocnej rdzy.
Oto sposób, w jaki można uzyskać dokładny typ (tj. Zdecydować między f32 a f64) w stabilnej rdzy:
prowadzi do
Aktualizacja
Odmiana turbin
jest nieco krótszy, ale nieco mniej czytelny.
źródło
float
, mówienie pomiędzyf32
if64
można to osiągnąć za pomocąstd::mem::size_of_val(&a)
Niektóre inne odpowiedzi nie działają, ale uważam, że typename paka działa.
Utwórz nowy projekt:
Zmodyfikuj Cargo.toml
Zmodyfikuj kod źródłowy
Dane wyjściowe to:
źródło
typename
nie działa ze zmiennymi bez wyraźnego typu w deklaracji. Uruchomienie go zmy_number
pytaniem powoduje następujący błąd: „nie można wywołać metodytype_name_of
na niejednoznacznym typie numerycznym{float}
. Help: musisz określić typ tego powiązania, np.f32
”0.65
i to działa dobrze:type of c 0.65 0.65 is f64
. oto moja wersja:rustc 1.38.0-nightly (69656fa4c 2019-07-13)
Jeśli chcesz tylko poznać typ swojej zmiennej podczas interaktywnego programowania, zdecydowanie polecam użycie rls (serwer języka rust) w edytorze lub ide. Następnie możesz po prostu na stałe włączyć lub przełączać zdolność najechania kursorem i po prostu umieścić kursor nad zmienną. W małym oknie dialogowym powinny pojawić się informacje o zmiennej, w tym o typie.
źródło