Skip to main content
Glama
lifetimes_references.rs6.01 kB
// lifetimes_references.rs - Demonstrates Rust lifetimes and references use std::fmt::Display; /// Function with explicit lifetime annotation pub fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } /// Multiple lifetime parameters pub fn first_word<'a, 'b>(x: &'a str, _y: &'b str) -> &'a str { x.split_whitespace().next().unwrap_or(x) } /// Lifetime with struct #[derive(Debug)] pub struct ImportantExcerpt<'a> { pub part: &'a str, } impl<'a> ImportantExcerpt<'a> { /// Lifetime elision in method pub fn level(&self) -> i32 { 3 } /// Method with lifetime annotation pub fn announce_and_return_part(&self, announcement: &str) -> &str { println!("Attention please: {}", announcement); self.part } } /// Struct with multiple lifetime parameters #[derive(Debug)] pub struct Context<'a, 'b> { pub primary: &'a str, pub secondary: &'b str, } impl<'a, 'b> Context<'a, 'b> { pub fn new(primary: &'a str, secondary: &'b str) -> Self { Self { primary, secondary } } pub fn get_primary(&self) -> &'a str { self.primary } pub fn get_secondary(&self) -> &'b str { self.secondary } } /// Static lifetime pub fn static_string() -> &'static str { "This string has static lifetime" } /// Generic with lifetime and trait bound pub fn longest_with_announcement<'a, T>( x: &'a str, y: &'a str, announcement: T, ) -> &'a str where T: Display, { println!("Announcement: {}", announcement); if x.len() > y.len() { x } else { y } } /// Reference to slice pub fn first_element<'a, T>(slice: &'a [T]) -> Option<&'a T> { slice.first() } /// Mutable reference with lifetime pub fn append_exclamation<'a>(s: &'a mut String) -> &'a str { s.push('!'); s.as_str() } /// Struct holding references #[derive(Debug)] pub struct Book<'a> { pub title: &'a str, pub author: &'a str, pub year: u32, } impl<'a> Book<'a> { pub fn new(title: &'a str, author: &'a str, year: u32) -> Self { Self { title, author, year } } pub fn display(&self) -> String { format!("{} by {} ({})", self.title, self.author, self.year) } } /// Lifetime bounds pub struct Ref<'a, T: 'a> { reference: &'a T, } impl<'a, T> Ref<'a, T> { pub fn new(reference: &'a T) -> Self { Self { reference } } pub fn get(&self) -> &'a T { self.reference } } /// Higher-ranked trait bounds (HRTBs) pub fn call_with_ref<F>(f: F) where F: for<'a> Fn(&'a str) -> &'a str, { let s = String::from("Hello"); let result = f(&s); println!("Result: {}", result); } /// Lifetime elision example 1 pub fn get_first_word(s: &str) -> &str { s.split_whitespace().next().unwrap_or("") } /// Lifetime elision example 2 pub fn parse_pair(s: &str) -> (&str, &str) { let parts: Vec<&str> = s.split(',').collect(); if parts.len() >= 2 { (parts[0], parts[1]) } else { ("", "") } } /// Struct with owned and borrowed data #[derive(Debug)] pub struct MixedData<'a> { pub owned: String, pub borrowed: &'a str, } impl<'a> MixedData<'a> { pub fn new(owned: String, borrowed: &'a str) -> Self { Self { owned, borrowed } } pub fn combine(&self) -> String { format!("{} {}", self.owned, self.borrowed) } } /// Iterator with lifetime pub struct StrSplitter<'a> { remainder: &'a str, delimiter: char, } impl<'a> StrSplitter<'a> { pub fn new(s: &'a str, delimiter: char) -> Self { Self { remainder: s, delimiter, } } } impl<'a> Iterator for StrSplitter<'a> { type Item = &'a str; fn next(&mut self) -> Option<Self::Item> { if self.remainder.is_empty() { return None; } match self.remainder.find(self.delimiter) { Some(pos) => { let result = &self.remainder[..pos]; self.remainder = &self.remainder[pos + 1..]; Some(result) } None => { let result = self.remainder; self.remainder = ""; Some(result) } } } } /// Lifetime with enum #[derive(Debug)] pub enum Either<'a, 'b> { Left(&'a str), Right(&'b str), } impl<'a, 'b> Either<'a, 'b> { pub fn get_value(&self) -> &str { match self { Either::Left(s) => s, Either::Right(s) => s, } } } /// Combining lifetimes pub fn combine_strings<'a>(strings: &'a [&'a str], separator: &str) -> String { strings.join(separator) } /// Reference counting considerations (not strictly lifetimes but related) use std::rc::Rc; pub struct SharedData { pub data: Rc<String>, } impl SharedData { pub fn new(s: String) -> Self { Self { data: Rc::new(s), } } pub fn clone_ref(&self) -> SharedData { Self { data: Rc::clone(&self.data), } } } /// Comparing references with different lifetimes pub fn compare_lengths<'a, 'b>(s1: &'a str, s2: &'b str) -> bool { s1.len() > s2.len() } #[cfg(test)] mod tests { use super::*; #[test] fn test_longest() { let s1 = "hello"; let s2 = "hi"; assert_eq!(longest(s1, s2), "hello"); } #[test] fn test_important_excerpt() { let text = "This is a test. This is important."; let excerpt = ImportantExcerpt { part: text }; assert_eq!(excerpt.level(), 3); } #[test] fn test_book() { let book = Book::new("1984", "George Orwell", 1949); assert!(book.display().contains("1984")); } #[test] fn test_str_splitter() { let text = "a,b,c"; let splitter = StrSplitter::new(text, ','); let parts: Vec<&str> = splitter.collect(); assert_eq!(parts, vec!["a", "b", "c"]); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Shashankss1205/CodeGraphContext'

If you have feedback or need assistance with the MCP directory API, please join our Discord server