Question

Convert an Integer to a String in Rust

ruststringtype-conversioninteger

Question

I am trying to compile Rust code that converts values from an integer to a string. I am following an older Rust for Rubyists tutorial that uses conversions such as "Fizz".to_str() and num.to_str() where num is an integer.

It seems that most or all uses of to_str() have been removed or deprecated. What is the current Rust way to convert an integer to a string?

These are the errors I get:

error: type `&'static str` does not implement any method in scope named `to_str`
error: type `int` does not implement any method in scope named `to_str`

Short Answer

By the end of this page, you will understand how Rust converts integers into strings using to_string() and format!, why older to_str() examples no longer compile, and how string conversion fits into everyday Rust programming.

Concept

In modern Rust, the usual way to convert an integer into a String is:

let num = 42;
let s = num.to_string();

The result is an owned String, which is Rust's growable string type.

Older Rust tutorials may show to_str(), but that API belonged to much earlier Rust versions and is no longer part of modern Rust. That is why current compilers report that the method does not exist.

Why this matters

Converting numbers to strings is common when you need to:

  • print values
  • build messages
  • create filenames or IDs
  • generate API responses
  • combine numbers with text

Rust is strict about types. An integer like 42 and a string like "42" are different kinds of values. Rust requires you to convert explicitly when needed, which helps prevent bugs.

The modern tools

to_string()

Use this when you want a direct conversion to String.

let x = 10;
let text = x.to_string();

format!

Use this when you want to build a larger string.

let x = 10;
let text = format!("Value: {}", x);

String slice vs String

This question also mentions "Fizz".to_str(). In modern Rust:

  • "Fizz" is already a string slice: &str
  • if you need an owned String, use:
let s = "Fizz".to_string();

So in current Rust:

  • integer to string: num.to_string()
  • string slice to owned string: "Fizz".to_string()
  • string slice as-is: just use "Fizz"

Mental Model

Think of Rust types as different container shapes.

  • An integer is like a calculator result: 42
  • A string is like a label printed on paper: "42"

Even if they look similar to a human, Rust treats them as different things.

to_string() is like asking Rust to print the value onto a new piece of paper.

  • 42 becomes "42"
  • true becomes "true"
  • "Fizz" can be copied into an owned String

So the rule of thumb is:

  • if you need text you can own and store, use to_string()
  • if you just want to display values inside a larger message, format! is often more convenient
Take Quiz

Syntax and Examples

Core syntax

let num = 123;
let s: String = num.to_string();

Example: integer to string

fn main() {
    let num = 25;
    let text = num.to_string();

    println!("num = {}", num);
    println!("text = {}", text);
}

What this does

  • num is an integer
  • num.to_string() converts it into a String
  • text now contains "25"

Example: building a message

fn main() {
    let score = 99;
    let message = format!("Your score is {}", score);

    println!("{}", message);
}

Use format! when you want to combine text and values into one string.

Example: converting a string slice to String

fn main() {
    let word = "Fizz";
    let owned = word.to_string();

    println!("{}", owned);
}

Here:

  • word is &str
  • owned is String

Example: FizzBuzz-style output

fn main() {
    let num = 7;

    let result = if num % 3 == 0 {
        "Fizz".to_string()
    } else {
        num.to_string()
    };

    println!("{}", result);
}

This is a common reason to convert integers into strings: different branches need to produce the same type.

Step by Step Execution

Consider this example:

fn main() {
    let num = 42;
    let text = num.to_string();
    println!("{}", text);
}

Step by step

1. let num = 42;

Rust creates an integer variable named num.

  • value: 42
  • type: inferred as an integer type such as i32

2. let text = num.to_string();

Rust calls the to_string() method on num.

  • it reads the integer value 42
  • it creates a new owned string
  • that string contains the characters 4 and 2

Now:

  • num is still an integer
  • text is a String

3. println!("{}", text);

Rust prints the string contents.

Output:

42

Trace table

LineVariableTypeValue
after line 2numinteger42
after line 3textString"42"

Another trace with branching

fn main() {
    let num = 9;
    let output = if num % 3 == 0 {
        "Fizz".to_string()
    } else {
        num.to_string()
    };

    println!("{}", output);
}

What happens

  • num is 9
  • num % 3 == 0 is true
  • Rust chooses the first branch
  • "Fizz".to_string() creates a String
  • output becomes "Fizz"
  • that string is printed

This shows why conversion matters: both branches must return the same type.

Real World Use Cases

Logging and messages

let user_id = 101;
let log = format!("User {} signed in", user_id);

Applications often turn numbers into strings for logs and status messages.

Building file names

let report_id = 7;
let filename = format!("report-{}.txt", report_id);

This is useful for generated files, exports, and cache keys.

API responses

A server may convert numeric data into strings when building JSON manually or preparing display text.

let count = 3;
let message = format!("Found {} results", count);

CLI tools

Command-line programs often display numeric values as text.

let exit_code = 1;
println!("Program exited with code {}", exit_code);

Conditional text output

FizzBuzz-like logic is also common in real systems:

  • display fallback labels
  • convert numbers for UI text
  • return error codes as readable strings
Take Quiz

Real Codebase Usage

In real Rust projects, developers usually use integer-to-string conversion in a few common patterns.

1. Formatting user-facing text

let retries = 3;
let msg = format!("Retry attempt {}", retries);

format! is often preferred when the number is only one part of a bigger message.

2. Returning a single consistent type

When if or match branches must all return the same type, to_string() is a simple fix.

let status = if is_admin {
    "admin".to_string()
} else {
    user_id.to_string()
};

3. Validation and error handling

Developers often convert numbers while constructing errors.

let age = 15;
let err = format!("Age {} is below the minimum", age);

4. Config and environment values

Some systems store values as strings even when the original data is numeric.

let port = 8080;
let port_text = port.to_string();

5. Logging without manual conversion

Often, explicit conversion is unnecessary inside macros like println!, format!, eprintln!, and logging macros because formatting handles it automatically.

let count = 12;
println!("count = {}", count);

So a useful rule is:

  • use to_string() when you specifically need a String
  • use formatting macros when you just need display output

Common Mistakes

1. Using old Rust methods like to_str()

Broken code:

let num = 5;
let s = num.to_str();

Why it fails:

  • to_str() is from old Rust examples
  • modern Rust uses to_string()

Correct code:

let num = 5;
let s = num.to_string();

2. Confusing &str and String

Broken code:

let s: &str = 5.to_string();

Why it fails:

  • to_string() returns String
  • &str is a borrowed string slice, not an owned string

Correct code:

let s: String = 5.to_string();

3. Converting when you do not need to

Unnecessary code:

let num = 8;
println!("{}", num.to_string());

Better:

let num = 8;
println!("{}", num);

Formatting macros can print integers directly.

4. Mixing branch types

Broken code:

let num = 4;
let result = if num % 2 == 0 {
    "even"
} else {
    num.to_string()
};

Why it fails:

  • one branch returns &str
  • the other returns String
  • Rust requires both branches to have the same type

Correct code:

let num = 4;
let result = if num % 2 == 0 {
    "even".to_string()
} else {
    num.to_string()
};

5. Expecting parsing and formatting to be the same thing

  • to_string() converts a value into text
  • parse() converts text into a typed value

Example:

let n = 42;
let s = n.to_string(); // number -> string
let m: i32 = s.parse().unwrap(); // string -> number

Comparisons

Related ways to work with text in Rust

TaskBest toolResultExample
Convert an integer to an owned stringto_string()String42.to_string()
Build a larger string with values insideformat!Stringformat!("ID: {}", 42)
Print a valueprintln!output onlyprintln!("{}", 42)
Use a string literal directlystring literal&str"Fizz"
Convert text into a numberparse()typed value"42".parse::<i32>()

to_string() vs format!

Featureto_string()format!
Simple direct conversionYesYes
Best for one value onlyYesUsually not necessary
Best for combining text and valuesNoYes
Returns StringYesYes

&str vs String

TypeMeaningOwnershipExample
&strborrowed string sliceborrowed"Fizz"
Stringowned, growable stringowned"Fizz".to_string()

If you only need fixed text, &str is often enough. If you need to build, store, or return owned text, use String.

Take Quiz

Cheat Sheet

Quick reference

Integer to string

let n = 42;
let s = n.to_string();

String literal to owned string

let s = "Fizz".to_string();

Build a string with values

let s = format!("Value: {}", 42);

Print without converting first

println!("{}", 42);

Rules to remember

  • to_str() is old Rust and should not be used in modern code.
  • to_string() returns a String.
  • String literals like "hello" are &str.
  • Use format! when combining numbers and text.
  • In if and match, all branches must return the same type.

Common patterns

let id = 1001.to_string();
let label = format!("user-{}", 1001);
let name = "Fizz".to_string();

Edge case reminder

This fails because the types differ:

let result = if true {
    "ok"
} else {
    1.to_string()
};

Make both branches the same type:

let result = if true {
    "ok".to_string()
} else {
    1.to_string()
};

FAQ

Why does to_str() not work in modern Rust?

Older Rust versions had different APIs. In current Rust, to_str() is no longer the correct method for this task. Use to_string() instead.

How do I convert an integer to a string in Rust?

Use:

let s = 123.to_string();

Should I use to_string() or format!?

Use to_string() for simple direct conversion. Use format! when building a larger string with other text.

Is "hello" already a string in Rust?

Yes, but it is a &str, which is a string slice. If you need an owned String, use "hello".to_string().

Can println! print integers without converting them first?

Yes.

println!("{}", 42);

What is the difference between String and &str?

String owns its data and can grow. &str is a borrowed view of string data.

How do I convert a string back into an integer?

Use parse():

let n: i32 = "42".parse().unwrap();

Why do my if branches fail when one returns text and the other returns a number string?

Rust requires both branches to return the same type. Convert both branches to String if needed.

Take Quiz

Mini Project

Description

Build a small Rust program that displays a label for a number. If the number is divisible by 3, show Fizz. Otherwise, convert the number into a string and display it. This mirrors a common beginner situation where different branches need to produce the same string type.

Goal

Create a program that returns a String from both branches of an if expression and prints the result.

Requirements

Requirement 1 Requirement 2 Requirement 3

Take Quiz

Keep learning

Related questions

View more