mirror of
https://github.com/leonardomso/rust-skills.git
synced 2026-09-14 19:33:21 +08:00
0016d5cfb2
Includes rules for: - Ownership and borrowing patterns - Error handling with thiserror/anyhow - Memory management and allocation - API design following Rust guidelines - Async/Tokio patterns - Performance optimization - Naming conventions - Type safety - Testing strategies - Documentation standards - Project structure - Linting configuration - Common anti-patterns to avoid
2.3 KiB
2.3 KiB
name-as-free
as_prefix: free reference conversion
Why It Matters
Consistent naming helps users understand API cost. as_ prefix signals a free (O(1), no allocation) conversion that returns a reference. This convention is used throughout the standard library.
The Convention
| Prefix | Cost | Ownership | Example |
|---|---|---|---|
as_ |
Free | &T -> &U |
str::as_bytes() |
to_ |
Expensive | &T -> U |
str::to_lowercase() |
into_ |
Variable | T -> U |
String::into_bytes() |
Examples
impl MyString {
// as_ - free reference conversion
pub fn as_str(&self) -> &str {
&self.inner
}
pub fn as_bytes(&self) -> &[u8] {
self.inner.as_bytes()
}
}
impl Wrapper<T> {
// as_ - returns reference to inner
pub fn as_inner(&self) -> &T {
&self.inner
}
pub fn as_inner_mut(&mut self) -> &mut T {
&mut self.inner
}
}
Standard Library Examples
// String
let s = String::from("hello");
let bytes: &[u8] = s.as_bytes(); // Free, returns &[u8]
let str_ref: &str = s.as_str(); // Free, returns &str
// Vec
let v = vec![1, 2, 3];
let slice: &[i32] = v.as_slice(); // Free, returns &[i32]
// Path
let p = PathBuf::from("/home");
let path: &Path = p.as_path(); // Free, returns &Path
// OsString
let os = OsString::from("hello");
let os_str: &OsStr = os.as_os_str(); // Free, returns &OsStr
Bad
impl MyType {
// BAD: as_ but allocates
pub fn as_string(&self) -> String {
format!("{}", self.value) // Allocates! Should be to_string()
}
// BAD: as_ but expensive
pub fn as_processed(&self) -> &ProcessedData {
// Actually does expensive computation
}
}
Good
impl MyType {
// GOOD: Free reference
pub fn as_str(&self) -> &str {
&self.inner
}
// GOOD: to_ signals allocation
pub fn to_string(&self) -> String {
format!("{}", self.value)
}
// GOOD: into_ signals ownership transfer
pub fn into_inner(self) -> Inner {
self.inner
}
}
See Also
- name-to-expensive -
to_prefix for expensive conversions - name-into-ownership -
into_prefix for ownership transfer