Question
In Rust, converting a string slice to an integer can be done like this in older code:
let my_int = from_str::<int>(my_str);
If I have a String, one approach is to first get a string slice and then convert it:
let my_int = from_str::<int>(my_string.as_slice());
Is there a way to convert a String directly to an integer, or is borrowing it as a string slice the correct approach?
Short Answer
By the end of this page, you will understand how Rust converts text into numbers, why String and &str are treated differently, and how to use modern Rust methods like .parse() to convert both String and &str into integer types safely.
Concept
In Rust, parsing a number from text means reading characters like "42" and turning them into a numeric type like i32 or u64.
The main idea is that Rust separates:
- Owned text:
String - Borrowed text:
&str
A String owns heap-allocated text. A &str is a view into text. Many parsing APIs work with &str because they only need to read the characters, not own them.
In modern Rust, the usual way to convert text to an integer is:
let n: i32 = "42".parse().unwrap();
This works because Rust provides parsing through the FromStr trait. Types like i32, u32, and usize implement this trait, so they know how to build themselves from text.
A can also be parsed easily because method calls can automatically borrow it as when needed:
Mental Model
Think of String as a book you own and &str as a page someone is reading from that book.
If you want to parse a number, the parser does not need to own the whole book. It just needs to read the page.
So when you write:
let s = String::from("123");
let n: i32 = s.parse().unwrap();
Rust is effectively saying:
sowns the text- the parser temporarily borrows that text
- the parser reads it and produces an integer
You still keep ownership of the original String unless you move it elsewhere.
This is why parsing usually works through borrowing rather than copying.
Syntax and Examples
Core syntax
In modern Rust, use .parse():
let n: i32 = "42".parse().unwrap();
Because .parse() returns a Result, you can also handle errors safely:
let n: Result<i32, _> = "42".parse();
Parsing a &str
fn main() {
let text = "123";
let number: i32 = text.parse().unwrap();
println!("{}", number);
}
Explanation:
textis a
Step by Step Execution
Consider this example:
fn main() {
let text = String::from("256");
let number: i32 = text.parse().unwrap();
println!("{}", number);
}
Step by step:
-
let text = String::from("256");- A
Stringis created. - It owns the text
"256".
- A
-
let number: i32 = text.parse().unwrap();.parse()is called ontext.- Rust borrows the contents of
textas&str. - It sees that you want an
i32. - It tries to convert the characters
2, , and into the integer .
Real World Use Cases
Parsing strings into integers appears in many practical Rust programs.
Command-line arguments
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() > 1 {
match args[1].parse::<i32>() {
Ok(port) => println!("Port: {}", port),
Err(_) => println!("Please provide a valid number"),
}
}
}
Used when reading values like ports, limits, or IDs.
User input
If a user types their age, quantity, or menu choice, the program receives text first. You must parse that text into a number before doing calculations.
Config files and environment variables
Environment variables are strings by default:
use std::env;
fn main() {
let timeout = env::var()
.()
.(|s| s.parse::<>().())
.();
(, timeout);
}
Real Codebase Usage
In real Rust codebases, developers usually combine parsing with validation and error handling.
Pattern: parse close to the input boundary
Convert text into a number as soon as you receive it.
fn parse_age(input: &str) -> Result<u8, std::num::ParseIntError> {
input.parse::<u8>()
}
This keeps the rest of your code working with proper numeric types instead of raw strings.
Pattern: guard clauses for invalid input
fn set_retry_count(input: &str) -> Result<u32, String> {
let count: u32 = input.parse().map_err(|_| "Invalid retry count".to_string())?;
if count > 10 {
return Err("Retry count must be 10 or less".to_string());
}
Ok(count)
}
First parse, then validate business rules.
Pattern: optional parsing with defaults
Common Mistakes
1. Forgetting that parsing can fail
Broken code:
fn main() {
let text = "abc";
let number: i32 = text.parse().unwrap();
println!("{}", number);
}
Problem:
"abc"is not a numberunwrap()will panic
Better:
fn main() {
let text = "abc";
match text.parse::<i32>() {
Ok(n) => println!("{}", n),
Err(_) => println!("Invalid number"),
}
}
2. Not specifying the target type
Broken code:
() {
= ;
= text.().();
}
Comparisons
| Concept | What it means | Common use |
|---|---|---|
String | Owned, growable text | Store and modify text |
&str | Borrowed view into text | Read text without ownership |
.parse::<i32>() | Convert text into a specific type | Parsing numbers from input |
unwrap() | Extract success value or panic | Quick demos, not ideal for production |
match on Result | Handle success and failure explicitly | Real applications |
String vs &str
Cheat Sheet
Quick reference
Parse a string slice
let n: i32 = "42".parse().unwrap();
Parse a String
let s = String::from("42");
let n: i32 = s.parse().unwrap();
Specify the type explicitly
let n = "42".parse::<u64>().unwrap();
Handle errors safely
match "42".parse::<i32>() {
Ok(n) => println!("{}", n),
Err(e) => (, e),
}
FAQ
Can I parse a String directly in Rust?
Yes. You can call .parse() directly on a String, and Rust will borrow it as &str automatically.
What is the difference between String and &str when parsing?
String owns the text, while &str is a borrowed view. Parsing usually only needs a borrowed view, so both work.
Why does parse() return a Result?
Because not every string is a valid number. Rust forces you to handle possible failure safely.
How do I parse an integer without crashing?
Use match, if let, or the ? operator instead of unwrap().
What replaces from_str::<int>(...) in modern Rust?
Use .parse::<i32>(), .parse::<u64>(), or another specific integer type.
Mini Project
Description
Build a small Rust program that reads a list of text values, converts the valid ones into integers, and skips invalid entries. This demonstrates how parsing works with string slices, error handling, and collecting usable numeric data from messy input.
Goal
Create a program that parses text values into integers and reports which values were valid or invalid.
Requirements
- Store several numeric and non-numeric text values in a collection.
- Attempt to convert each value into an integer.
- Print valid integers.
- Print a message for invalid values.
- Keep a final list of all successfully parsed integers.
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.