Naming Conventions
Rust enforces a consistent set of naming conventions across the entire ecosystem (codified in RFC 430). Unlike languages where naming styles are merely informal style suggestions, rustc actively checks identifier casing and emits compiler warnings whenever a variable, type, function, or constant deviates from standard casing.
Identifier Casing Reference Table
| Item Kind | Casing Convention | Examples | Compiler Lint Triggered on Violation |
|---|---|---|---|
| Crates | snake_case (or kebab-case in Cargo.toml) |
serde_json, tokio_util |
non_snake_case |
Modules (mod) |
snake_case |
network_client, file_io |
non_snake_case |
Functions (fn) and Methods |
snake_case |
parse_header, is_empty |
non_snake_case |
| Local Variables and Parameters | snake_case |
user_id, max_retries |
non_snake_case |
Structs (struct) and Unions |
UpperCamelCase (PascalCase) |
HttpClient, TcpStream |
non_camel_case_types |
Enums (enum) |
UpperCamelCase |
IpAddr, Ordering |
non_camel_case_types |
| Enum Variants | UpperCamelCase |
Some, None, NotFound |
non_camel_case_types |
Traits (trait) |
UpperCamelCase |
Iterator, FromStr, Display |
non_camel_case_types |
Type Aliases (type) |
UpperCamelCase |
IoResult, NodeId |
non_camel_case_types |
| Generic Type Parameters | Concise UpperCamelCase (often 1 letter) |
T, E, K, V, Item |
non_camel_case_types |
Constants (const) |
SCREAMING_SNAKE_CASE |
MAX_CONNECTIONS, DEFAULT_PORT |
non_upper_case_globals |
Static Variables (static) |
SCREAMING_SNAKE_CASE |
GLOBAL_LOGGER, INSTANCE_COUNT |
non_upper_case_globals |
| Lifetimes | Short lowercase starting with ' |
'a, 'de, 'static, 'src |
non_snake_case |
Macros (macro_rules!) |
snake_case! |
println!, vec!, assert_eq! |
non_snake_case |
const MAX_ITEMS: usize = 100;
struct InventoryItem {
item_id: u64,
in_stock: bool,
}
enum StockStatus {
Available,
OutOfStock,
}
fn check_availability(item: &InventoryItem) -> StockStatus {
if item.in_stock && (item.item_id as usize) < MAX_ITEMS {
StockStatus::Available
} else {
StockStatus::OutOfStock
}
}
fn main() {
let sample_item = InventoryItem {
item_id: 42,
in_stock: true,
};
let current_status = check_availability(&sample_item);
println!("Available: {}", matches!(current_status, StockStatus::Available));
}
Available: true
Acronyms and Initialisms in UpperCamelCase
In UpperCamelCase, acronyms and initialisms (such as HTTP, UUID, URL, JSON, TCP, and IO) are treated as single words: only the first letter is capitalized (Uuid, HttpRequest, JsonParser, Stdin), rather than all-caps (UUID, HTTPRequest, JSONParser):
| Avoid (All-Caps Acronym) | Idiomatic Rust (UpperCamelCase / snake_case) |
|---|---|
struct HTTPServer |
struct HttpServer |
struct UUIDGenerator |
struct UuidGenerator |
enum JSONValue |
enum JsonValue |
fn parse_HTTP_URL() |
fn parse_http_url() |
Method Prefix Conventions (as_, to_, into_)
Standard library and ecosystem types follow a strict naming convention for conversion and accessor methods based on ownership and runtime cost:
| Prefix | Ownership of self |
Allocation / Runtime Cost | Examples |
|---|---|---|---|
as_... |
Borrows &self or &mut self |
Free ($O(1)$ view conversion, no allocation) | str::as_bytes(&self) -> &[u8], Path::as_os_str(&self) |
to_... |
Borrows &self |
Expensive (allocates a new buffer or performs non-trivial work) | str::to_lowercase(&self) -> String, slice::to_vec(&self) -> Vec<T> |
into_... |
Consumes self by value |
Variable (transfers ownership, often $O(1)$ zero-copy unwrap) | String::into_bytes(self) -> Vec<u8>, Box::into_inner(self) |
fn main() {
let text = String::from("Rust");
// 1. `as_bytes(&self)`: free borrowed view `&[u8]`; `text` remains valid
let byte_slice: &[u8] = text.as_bytes();
println!("as_bytes: {byte_slice:?}");
// 2. `to_uppercase(&self)`: allocates a new `String`; `text` remains valid
let upper: String = text.to_uppercase();
println!("to_upper: {upper}");
// 3. `into_bytes(self)`: consumes `text` and returns its underlying `Vec<u8>` buffer directly
let owned_bytes: Vec<u8> = text.into_bytes();
println!("into_bytes: {owned_bytes:?}");
}
as_bytes: [82, 117, 115, 116]
to_upper: RUST
into_bytes: [82, 117, 115, 116]
Getter, Predicate, and Iterator Method Names
- Getters (
field_name, noget_prefix): Unlike Java or C++ (get_width()), Rust getters omitget_and use the bare field name:fn width(&self) -> u32,fn len(&self) -> usize. Thegetname is reserved for fallible index/key lookup methods that returnOption<&T>(such asslice.get(0)ormap.get("key")). - Boolean predicates (
is_...,has_...): Methods returningboolbegin withis_orhas_(is_empty(),is_ascii(),is_some()). - Collection iterators (
iter,iter_mut,into_iter):.iter()yields shared references (&T)..iter_mut()yields mutable references (&mut T)..into_iter()consumes the collection and yields owned values (T).
Compiler Warnings on Naming Violations
When you violate a naming convention, the program still compiles, but rustc emits a detailed lint warning suggesting the idiomatic name:
struct user_profile {
UserName: String,
}
fn CalculateScore( InputValue: i32 ) -> i32 {
InputValue * 2
}
fn main() {
let p = user_profile { UserName: String::from("ferris") };
println!("{} -> {}", p.UserName, CalculateScore(10));
}
warning: type `user_profile` should have an upper camel case name
--> src/main.rs:1:8
|
1 | struct user_profile {
| ^^^^^^^^^^^^ help: convert the identifier to upper camel case: `UserProfile`
|
= note: `#[warn(non_camel_case_types)]` on by default
warning: structure field `UserName` should have a snake case name
--> src/main.rs:2:5
|
2 | UserName: String,
| ^^^^^^^^ help: convert the identifier to snake case: `user_name`
|
= note: `#[warn(non_snake_case)]` on by default
warning: function `CalculateScore` should have a snake case name
--> src/main.rs:5:4
|
5 | fn CalculateScore( InputValue: i32 ) -> i32 {
| ^^^^^^^^^^^^^^ help: convert the identifier to snake case: `calculate_score`
When interacting with foreign C libraries (FFI) where external structs or functions must keep their exact C names, suppress the lint on that specific declaration with #[allow(non_camel_case_types)] or #[allow(non_snake_case)].