Eu tenho o seguinte:
let mut my_number = 32.90;
Como imprimo o tipo de my_number
?
Usando type
e type_of
não funcionou. Existe outra maneira de imprimir o tipo do número?
Se você apenas deseja descobrir o tipo de uma variável e está disposto a fazê-lo em tempo de compilação, pode causar um erro e solicitar que o compilador a escolha.
Por exemplo, defina a variável para um tipo que não funcione :
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}`
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();
| ^^^^^^^^^^^^
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
| ^^^^^^^^^^^^
Eles revelam o tipo, que neste caso não é totalmente resolvido. É chamado de "variável de ponto flutuante" no primeiro exemplo e " {float}
" nos três exemplos; esse é um tipo parcialmente resolvido que pode terminar f32
ou f64
, dependendo de como você o usa. " {float}
" Não é um nome de tipo legal, é um espaço reservado que significa "Não tenho muita certeza do que é isso", mas é um número de ponto flutuante. No caso de variáveis de ponto flutuante, se você não o restringir, o padrão será f64
¹. (Um literal inteiro não qualificado será padronizado como i32
.)
Veja também:
Still Ainda pode haver maneiras de confundir o compilador para que ele não possa decidir entre f32
e f64
; Não tenho certeza. Costumava ser tão simples quanto 32.90.eq(&32.90)
, mas isso trata tanto como f64
agora e é feliz, então eu não sei.
:?
já há muito tempo foi implementado manualmente. Mais importante, porém, astd::fmt::Debug
implementação (para isso é o que:?
usa) para tipos de número não inclui mais um sufixo para indicar de que tipo ele é.ImageBuffer<_, Vec<_>>
que não me ajude muito quando estou tentando escrever uma função que usa uma dessas coisas como parâmetro. E isso acontece no código que de outra forma compila até eu adicionar o:()
. Não existe melhor maneira?Há uma função instável
std::intrinsics::type_name
que pode lhe dar o nome de um tipo, embora você precise usar uma compilação noturna do Rust (é improvável que isso funcione no Rust estável). Aqui está um exemplo:fonte
#![feature(core_intrinsics)]
print_type_of
está usando referências (&T
), não valores (T
), então você deve passar&&str
ao invés de&str
; isto é,print_type_of(&"foo")
e nãoprint_type_of("foo")
.std::any::type_name
é estável desde a ferrugem 1.38: stackoverflow.com/a/58119924Você pode usar a
std::any::type_name
função Isso não precisa de um compilador noturno ou de uma caixa externa, e os resultados são bastante corretos:Esteja avisado: como dito na documentação, essas informações devem ser usadas apenas para fins de depuração:
Se você deseja que sua representação de tipo permaneça a mesma entre as versões do compilador, use uma característica, como na resposta do phicr .
fonte
Se você conhece todos os tipos de antemão, pode usar características para adicionar um
type_of
método:Nada de intrísico ou nada, portanto, embora mais limitada,
essa é a única solução que fornece uma string e é estável.(veja a resposta de French Boiethios ) No entanto, é muito trabalhoso e não leva em consideração os parâmetros de tipo, para que pudéssemos ...Vamos usá-lo:
resultado:
Rust Playground
fonte
UPD O seguinte não funciona mais. Verifique a resposta de Shubham para correção.
Confira
std::intrinsics::get_tydesc<T>()
. Ele está no estado "experimental" no momento, mas não há problema se você estiver apenas invadindo o sistema de tipos.Confira o seguinte exemplo:
É isso que é usado internamente para implementar o famoso
{:?}
formatador.fonte
** ATUALIZAÇÃO ** Isso não foi verificado para funcionar recentemente.
Eu montei uma pequena caixa para fazer isso com base na resposta do vbo. Ele fornece uma macro para retornar ou imprimir o tipo.
Coloque isso no seu arquivo Cargo.toml:
Então você pode usá-lo assim:
fonte
#![feature]
não pode ser usado no canal de lançamento estável`Você também pode usar a abordagem simples de utilizar a variável em
println!("{:?}", var)
. SeDebug
não estiver implementado para o tipo, você poderá ver o tipo na mensagem de erro do compilador:( cercadinho )
Está sujo, mas funciona.
fonte
Debug
não for implementado - esse é um caso bastante improvável. Uma das primeiras coisas que você deve fazer para qualquer estrutura é adicionar#[derive(Debug)]
. Eu acho que os tempos em que você não querDebug
são muito pequenos.println!("{:?}", unknown_var);
? É uma interpolação de cordas, mas por que o:?
interior dos colchetes? @DenisKolodinDebug
porque não está implementado, mas você pode usá-lo{}
também.Existe uma resposta @ChrisMorgan para obter um tipo aproximado ("float") em ferrugem estável e há uma resposta @ShubhamJain para obter um tipo preciso ("f64") através da função instável em ferrugem noturna.
Agora, aqui está uma maneira de obter um tipo preciso (ou seja, decidir entre f32 e f64) com ferrugem estável:
resulta em
Atualizar
A variação do peixe-boi
é um pouco mais curto, mas um pouco menos legível.
fonte
float
, dizendo entref32
ef64
pode ser realizado comstd::mem::size_of_val(&a)
Algumas outras respostas não funcionam, mas acho que a caixa de nomes de tipos funciona.
Crie um novo projeto:
Modifique o Cargo.toml
Modifique seu código fonte
A saída é:
fonte
typename
não funciona com variáveis sem tipo explícito na declaração. Executá-lo commy_number
a partir da pergunta dá o seguinte erro "não pode chamar o métodotype_name_of
de tipo numérico ambígua{float}
ajuda: você deve especificar um tipo para essa ligação, como.f32
"0.65
e funciona bem:type of c 0.65 0.65 is f64
. aqui está a minha versão:rustc 1.38.0-nightly (69656fa4c 2019-07-13)
Se você está apenas querendo saber o tipo de sua variável durante o desenvolvimento interativo, eu recomendo o uso de rls (rust language server) dentro do seu editor ou ide. Você pode simplesmente ativar ou alternar permanentemente a capacidade de passar o mouse e apenas colocar o cursor sobre a variável. Um pequeno diálogo deve apresentar informações sobre a variável, incluindo o tipo.
fonte