R
Vidas Úteis
Rust Syntax Guide
Garantir que as referências são válidas enquanto forem necessárias
Vidas Úteis
Garantir que as referências são válidas enquanto forem necessárias
Rust vidas úteis (rust)
// Lifetime basics
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
}
// Function with lifetime annotation
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
// Struct with lifetime
struct ImportantExcerpt<'a> {
part: &'a str,
}
impl<'a> ImportantExcerpt<'a> {
fn level(&self) -> i32 {
3
}
// Method with lifetime elision
fn announce_and_return_part(&self, announcement: &str) -> &str {
println!("Attention please: {}", announcement);
self.part
}
}
// Static lifetime
fn static_lifetime() -> &'static str {
"I have a static lifetime."
}
// Lifetime with generics
fn longest_with_an_announcement<'a, T>(
x: &'a str,
y: &'a str,
ann: T,
) -> &'a str
where
T: std::fmt::Display,
{
println!("Announcement! {}", ann);
if x.len() > y.len() {
x
} else {
y
}
}
// Generic lifetime parameters
struct Pair<'a, T> {
x: &'a T,
y: &'a T,
}
impl<'a, T> Pair<'a, T> {
fn new(x: &'a T, y: &'a T) -> Self {
Self { x, y }
}
// Return reference with same lifetime
fn first(&self) -> &'a T {
self.x
}
}
fn main2() {
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
// string2 goes out of scope here
}
// But result is still valid because it refers to string1
println!("The longest string is {}", result);
// Using struct with lifetime
let novel = String::from("Call me Ishmael. Some years ago...");
let first_sentence = novel.split('.').next().unwrap();
let excerpt = ImportantExcerpt {
part: first_sentence,
};
println!("Excerpt: {}", excerpt.part);
println!("Level: {}", excerpt.level());
// Static lifetime
let static_str = static_lifetime();
println!("{}", static_str);
// Generic function
let result2 = longest_with_an_announcement(
string1.as_str(),
"short",
"Here's the result"
);
println!("Result: {}", result2);
// Generic struct
let pair = Pair::new(&42, &24);
println!("First: {}", pair.first());
}
// Lifetime elision rules (compiler infers lifetimes)
// Rule 1: Each parameter gets its own lifetime
// Rule 2: If there's exactly one input lifetime, it's assigned to all outputs
// Rule 3: If there are multiple input lifetimes, and one is &self or &mut self,
// that lifetime is assigned to all outputs
fn first_word(s: &str) -> &str { // Elided: fn first_word<'a>(s: &'a str) -> &'a str
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
&s[..]
}
Explanation
As vidas úteis são um conceito central em Rust que garantem que todas as referências são válidas durante o tempo em que são usadas. Elas são anotações que dizem ao compilador como os parâmetros de vida útil genéricos de múltiplas referências se relacionam entre si.
Common Use Cases
- Prevenir referências penduradas
- Garantir segurança de memória em funções que tomam referências
- Trabalhar com estruturas de dados complexas que envolvem referências
Related Rust Syntax
Master Vidas Úteis in Rust
Understanding Vidas Úteis is fundamental to writing clean and efficient Rust code. This comprehensive guide provides you with practical examples and detailed explanations to help you master this important concept.
Whether you're a beginner learning the basics or an experienced developer looking to refresh your knowledge, our examples cover real-world scenarios and best practices for using Vidas Úteis effectively in your Rust projects.
Key Takeaways
- Prevenir referências penduradas
- Garantir segurança de memória em funções que tomam referências
- Trabalhar com estruturas de dados complexas que envolvem referências