Question
I have the following Rust code:
let mut my_number = 32.90;
How can I print the type of my_number?
I tried using type and type_of, but those did not work. Is there another way to display the variable's type in Rust?
Short Answer
By the end of this page, you will understand how Rust determines a variable's type, why Rust does not have a simple built-in type() function like some other languages, and how to inspect a type using std::any::type_name. You will also learn what type Rust infers for numeric literals such as 32.90, how type inference works, and common mistakes beginners make when trying to print a type.
Concept
Rust is a statically typed language. That means every value has a type known at compile time, even if you do not write the type explicitly.
For example:
let mut my_number = 32.90;
Rust infers the type of my_number from the value 32.90. A floating-point literal like 32.90 is inferred as f64 by default unless you specify otherwise.
So this is effectively treated like:
let mut my_number: f64 = 32.90;
Unlike dynamic languages, Rust does not usually encourage "printing a type" during normal program logic, because types are mainly a compile-time concept. However, for debugging or learning, you can inspect a type using:
std::any::type_name::<T>()
or by wrapping it in a helper function that accepts a reference to a value.
This matters because understanding type inference helps you:
- read Rust code more confidently
- avoid mismatched-type errors
- choose the correct numeric type like
i32, , or
Mental Model
Think of a Rust variable like a labeled storage box in a warehouse.
- The value is what is inside the box.
- The type is the label on the outside of the box.
- Rust wants that label to be clear before the program runs.
When you write:
let my_number = 32.90;
Rust looks at the value and decides which label fits best. For a decimal number, the default label is usually f64.
Printing the type is like asking, "What label did Rust put on this box?" Rust does not have a casual built-in type() function for this, but it does give you tools to inspect the label when needed.
Syntax and Examples
The most common way to print a variable's type in Rust is to use std::any::type_name with a helper function.
use std::any::type_name;
fn print_type_of<T>(_: &T) {
println!("{}", type_name::<T>());
}
fn main() {
let mut my_number = 32.90;
print_type_of(&my_number);
}
Output:
f64
How it works
print_type_of<T>is a generic function.Tbecomes the actual type of the value you pass in.type_name::<T>()returns that type as a string.&my_numberpasses a reference, which avoids moving the value.
Explicit type example
use std::any::type_name;
fn print_type_of<T>(_: &T) {
println!(, type_name::<T>());
}
() {
= ;
: = ;
: = ;
(&a);
(&b);
(&c);
}
Step by Step Execution
Consider this example:
use std::any::type_name;
fn print_type_of<T>(_: &T) {
println!("{}", type_name::<T>());
}
fn main() {
let my_number = 32.90;
print_type_of(&my_number);
}
Step-by-step
- Rust sees
let my_number = 32.90; - The value
32.90is a floating-point literal. - Because no other type information is given, Rust chooses the default floating-point type:
f64. print_type_of(&my_number)is called.- Rust infers that
Tinprint_type_of<T>must bef64. - Inside the function,
type_name::<T>()becomestype_name::<f64>(). println!printsf64.
Trace with another example
Real World Use Cases
Even though printing a type is mostly for debugging or learning, type inspection is useful in several practical situations.
Debugging generic code
When writing generic functions or reusable utilities, you may want to confirm what concrete type Rust inferred.
use std::any::type_name;
fn debug_type<T>(_: &T) {
println!("Type: {}", type_name::<T>());
}
Learning type inference
Beginners often wonder what type Rust chooses for:
- integer literals
- float literals
- string literals
- references
- collections
Printing types helps verify your understanding.
Troubleshooting compiler errors
If Rust reports a mismatch between expected and actual types, inspecting surrounding values can help you understand the issue.
Working with numeric code
In math, finance, graphics, or APIs, it matters whether a number is:
i32u64f32f64
Knowing the inferred type helps avoid bugs and conversion issues.
Real Codebase Usage
In real Rust projects, developers usually do not print types in production code. Instead, they use type inspection as a temporary debugging or teaching tool.
Common patterns include:
1. Making types explicit when clarity matters
let price: f64 = 32.90;
let count: u32 = 5;
This is often better than printing the type later.
2. Using helper functions during debugging
use std::any::type_name;
fn type_of<T>(_: &T) -> &'static str {
type_name::<T>()
}
This can be used in logs or tests.
3. Adding explicit conversions
If a function expects a specific type, developers convert values instead of relying only on inference.
let value = 10;
let as_float = value as f64;
4. Guarding against wrong assumptions
A developer may assume a number is f32, but Rust may infer . In real codebases, this is usually solved by annotating the type:
Common Mistakes
Mistake 1: Expecting a built-in type() function
Rust does not have a Python-style type(variable) function.
Broken idea:
let my_number = 32.90;
println!("{}", type(my_number));
Why it fails:
typeis not a built-in Rust function for runtime inspection.
Use this instead:
use std::any::type_name;
fn print_type_of<T>(_: &T) {
println!("{}", type_name::<T>());
}
Mistake 2: Forgetting that float literals default to f64
let x = 32.90;
Many beginners assume this is f32, but it is f64 by default.
To make it f32:
Comparisons
| Approach | What it does | Best use | Example |
|---|---|---|---|
| Type inference | Lets Rust choose the type | Clean, simple code | let x = 32.90; |
| Type annotation | You specify the type directly | Clarity and control | let x: f32 = 32.90; |
| Type suffix | You attach the type to the literal | Short numeric declarations | let x = 32.90_f32; |
std::any::type_name | Prints or returns a type name | Debugging and learning | type_name::<T>() |
Inference vs explicit annotation
Cheat Sheet
// Default float type
let x = 32.90; // f64
// Explicit type annotation
let x: f32 = 32.90;
// Literal suffix
let x = 32.90_f32;
let y = 10_i64;
// Print a variable's type
use std::any::type_name;
fn print_type_of<T>(_: &T) {
println!("{}", type_name::<T>());
}
// Use it
let value = 32.90;
print_type_of(&value); // prints: f64
Rules to remember
- Rust is statically typed.
- Types are usually known at compile time.
- Rust uses type inference when possible.
32.90defaults tof64.5defaults toi32.- Use
std::any::type_name::<T>()to inspect a type.
FAQ
How do I print the type of a variable in Rust?
Use std::any::type_name inside a generic helper function:
use std::any::type_name;
fn print_type_of<T>(_: &T) {
println!("{}", type_name::<T>());
}
What type is 32.90 in Rust?
By default, 32.90 is inferred as f64.
Does Rust have a built-in type() function?
No. Rust does not provide a simple built-in type(variable) function like some dynamic languages.
Can I get a variable's type at runtime in Rust?
You can inspect a type name for debugging using std::any::type_name, but Rust's type system is mainly compile-time focused.
How do I make a float f32 instead of f64?
Use a type annotation or suffix:
let x: f32 = ;
= ;
Mini Project
Description
Build a small Rust program that prints both values and their inferred types. This helps you practice Rust type inference and learn how different literals are interpreted by the compiler.
Goal
Create a program that displays several variables and the type Rust assigns to each one.
Requirements
- Create at least four variables with different kinds of values.
- Include at least one integer, one floating-point number, one string slice, and one boolean.
- Write a reusable helper function to print a variable's type.
- Print both the variable's value and its type.
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Default Function Arguments in Rust: What to Use Instead
Learn how Rust handles default function arguments, why they are not supported, and practical patterns to achieve similar behavior.
Fixing Rust "linker 'cc' not found" on Debian in WSL
Learn why Rust shows "linker 'cc' not found" on Debian in WSL and how to fix it by installing the required C build tools.