You cannot directly borrow a subset of fields from a struct because Rust's borrow checker treats a struct as a single unit; borrowing the whole struct prevents borrowing any of its fields, and vice versa. To work around this, you must either borrow the entire struct and access specific fields through that reference, or implement a custom method that returns references to the specific fields you need.
The most common pattern is to borrow the whole struct and then access the fields you need via the reference. This is safe and idiomatic because the compiler tracks the lifetime of the reference to the struct, ensuring any field references derived from it remain valid.
struct Data {
name: String,
value: i32,
active: bool,
}
fn process_name(d: &Data) {
// Borrow the whole struct, then access the specific field
let name_ref: &str = &d.name;
println!("Name: {}", name_ref);
}
If you need to return references to specific fields from a function without returning the whole struct, define a method on the struct that returns the specific reference. This encapsulates the borrowing logic and makes the API clearer.
struct Config {
host: String,
port: u16,
timeout: u32,
}
impl Config {
// Returns a reference to just the host field
fn host(&self) -> &str {
&self.host
}
// Returns a reference to just the port field
fn port(&self) -> &u16 {
&self.port
}
}
fn main() {
let cfg = Config {
host: "localhost".to_string(),
port: 8080,
timeout: 30,
};
// Borrow only the specific parts we need
let h: &str = cfg.host();
let p: &u16 = cfg.port();
println!("Connecting to {} on {}", h, p);
}
Attempting to manually split a struct into parts (e.g., let (name, value) = &data;) is impossible because Rust does not support destructuring references to structs into multiple independent references. If you need mutable access to multiple fields simultaneously, you must borrow the whole struct mutably (&mut Data) and modify fields through that single mutable reference. Trying to create two mutable references to different fields of the same struct at the same time will result in a compile-time error, as it violates Rust's aliasing rules.