=>Punctuation
Explanation
=> separates a match arm's pattern from the code
that runs when it matches: pattern => expression. It appears only inside a
match block's arm list — the arm's full grammar (comma rules, guards,
or-patterns via |, bindings via @) is covered on the match page and
isn't repeated here.
Disambiguation from ->: => (fat arrow) is unrelated to
-> (thin arrow) despite the visual similarity and both
appearing near function-like constructs. -> introduces a function's or
closure's return type (fn f() -> i32); => separates a match arm's
pattern from its body. Mixing them up is a common slip for newcomers,
especially coming from languages (JavaScript, Kotlin, C#) where => itself
introduces a lambda/arrow-function body. Rust's closures use |params| body
instead, with no arrow at all unless an explicit return type is spelled out
via ->.
=> also appears in macro_rules! arms, separating a macro's matcher
pattern from its expansion ((pattern) => { expansion };). That is a
distinct, macro-specific grammar with its own matching rules — covered on
the macro syntax pages, not here.
Usage examples
Separating a match arm's pattern from its result
let day = 3;
let name = match day {
1 => "Monday", // <- `=>` separates the pattern from what runs if it matches
2 => "Tuesday",
3 => "Wednesday",
_ => "unknown",
};
println!("{name}");
Branching on data (pattern matching)
Looking up a playing card's color from its suit is a one-to-one mapping —
each arm's => leads straight to the result, no further computation
needed.
enum Suit {
Hearts,
Diamonds,
Clubs,
Spades,
}
fn color(suit: &Suit) -> &'static str {
match suit {
Suit::Hearts => "red", // <- `=>` separates the pattern from its result
Suit::Diamonds => "red",
Suit::Clubs => "black",
Suit::Spades => "black",
}
}
println!("{}", color(&Suit::Diamonds));
A one-line arm body after => keeps a simple mapping
scannable at a glance — the
Rust Book uses this
same terse, single-expression-per-arm style whenever an arm's logic doesn't
need a block.
Handling and propagating errors
Reporting on a network fetch needs a different message per outcome — here
=> leads into a multi-step expression rather than a single literal.
fn describe_fetch(result: Result<String, String>) -> String {
match result {
Ok(body) => format!("received {} bytes", body.len()), // <- `=>` here leads into a longer expression
Err(reason) => format!("fetch failed: {reason}"),
}
}
println!("{}", describe_fetch(Ok("hello".to_string())));
Whether the arm's expression is a bare literal or a
multi-step format! call, => marks the same boundary — the pattern ends,
the value to produce begins — which is why arms of very different
complexity can sit in the same match without special-casing the
separator.