Created
February 12, 2025 09:24
-
-
Save sffc/9eb7a74de36d3baca3b58196f253169d to your computer and use it in GitHub Desktop.
Examples from Comprehensive Rust @ University of Bergen, January 2025
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Debug)] | |
struct CarRace { | |
name: String, | |
laps: Vec<i32>, | |
} | |
impl CarRace { | |
// No receiver, a static method | |
fn new(name: &str) -> Self { | |
Self { name: String::from(name), laps: Vec::new() } | |
} | |
// Exclusive borrowed read-write access to self | |
fn add_lap(&mut self, lap: i32) { | |
self.laps.push(lap); | |
} | |
fn borrow_laps<'a>(&'a self) -> &'a [i32] { | |
self.laps.as_slice() | |
} | |
// Shared and read-only borrowed access to self | |
fn print_laps(&self) { | |
println!("Recorded {} laps for {}:", self.laps.len(), self.name); | |
for (idx, lap) in self.laps.iter().enumerate() { | |
println!("Lap {idx}: {lap} sec"); | |
} | |
} | |
// Exclusive ownership of self (covered later) | |
fn finish(self) -> Vec<i32> { | |
let total: i32 = self.laps.iter().sum(); | |
println!("Race {} is finished, total lap time: {}", self.name, total); | |
self.laps | |
} | |
} | |
fn helper(mut race: CarRace) -> CarRace { | |
race.add_lap(42); | |
race | |
} | |
fn main() { | |
let mut race = CarRace::new("Monaco Grand Prix"); | |
race.add_lap(70); | |
race.add_lap(68); | |
race.print_laps(); | |
race.add_lap(71); | |
println!("{:?}", race.borrow_laps()); | |
race.print_laps(); | |
let mut race = helper(race); | |
let v = race.finish(); | |
// race.add_lap(42); | |
println!("{v:?}"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Pet { | |
/// Return a sentence from this pet. | |
fn talk(&self) -> String; | |
/// Print a string to the terminal greeting this pet. | |
fn greet(&self) { | |
println!("Oh you're a cutie! What's your name? {}", self.talk()); | |
} | |
} | |
#[derive(Debug)] | |
struct Dog { | |
name: String, | |
age: i8, | |
// no_debug: NoDebug, | |
} | |
struct NoDebug {} | |
impl Pet for Dog { | |
fn talk(&self) -> String { | |
format!("Woof, my name is {}!", self.name) | |
} | |
} | |
// #[derive(Debug)] | |
enum Color { | |
Brown, | |
White, | |
Black, | |
Orange | |
} | |
impl std::fmt::Debug for Color { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
match self { | |
Self::Brown => write!(f, "Brown"), | |
Self::White => write!(f, "White"), | |
Self::Black => write!(f, "Black"), | |
Self::Orange => write!(f, "Orange"), | |
} | |
} | |
} | |
struct Cat { | |
name: String, | |
color: Color | |
} | |
impl Pet for Cat { | |
fn talk(&self) -> String { | |
format!("My name is {} and my color is {:?}", self.name, self.color) | |
} | |
fn greet(&self) { | |
println!("Hiss!"); | |
} | |
} | |
fn main() { | |
let fido = Dog { name: String::from("Fido"), age: 5 }; | |
fido.greet(); | |
let fluffy = Cat { name: "Fluffy".into(), color: Color::Orange }; | |
fluffy.greet(); | |
println!("{}", fluffy.talk()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[macro_export] | |
macro_rules! my_macro { | |
(plus3: $x:ident) => { | |
fn $x(y: u32) -> u32 { | |
y + 3 | |
} | |
}; | |
(plus5: $x:ident) => { | |
fn $x(y: u32) -> u32 { | |
y + 5 | |
} | |
}; | |
} | |
pub use my_macro as my_macro; | |
// helpers::my_macro!(plus5: my_fn_name); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// An operation to perform on two subexpressions. | |
#[derive(Debug)] | |
enum Operation { | |
Add, | |
Sub, | |
Mul, | |
Div, | |
} | |
/// An expression, in tree form. | |
#[derive(Debug)] | |
enum Expression<'a> { | |
/// An operation on two subexpressions. | |
Op { op: Operation, left: &'a Expression<'a>, right: &'a Expression<'a> }, | |
/// A literal value | |
Value(i64), | |
} | |
fn eval(e: &Expression) -> i64 { | |
match e { | |
Expression::Op { op, left, right } => { | |
let left = eval(left); | |
let right = eval(right); | |
match op { | |
Operation::Add => left + right, | |
Operation::Sub => left - right, | |
Operation::Mul => left * right, | |
Operation::Div => left / right, | |
} | |
}, | |
Expression::Value(v) => *v, | |
} | |
} | |
#[test] | |
fn test_value() { | |
assert_eq!(eval(&Expression::Value(19)), 19); | |
} | |
#[test] | |
fn test_sum() { | |
assert_eq!( | |
eval(&Expression::Op { | |
op: Operation::Add, | |
left: &Expression::Value(10), | |
right: &Expression::Value(20), | |
}), | |
30 | |
); | |
} | |
#[test] | |
fn test_recursion() { | |
let term1 = Expression::Op { | |
op: Operation::Mul, | |
left: &Expression::Value(10), | |
right: &Expression::Value(9), | |
}; | |
let term2 = Expression::Op { | |
op: Operation::Mul, | |
left: &Expression::Op { | |
op: Operation::Sub, | |
left: &Expression::Value(3), | |
right: &Expression::Value(4), | |
}, | |
right: &Expression::Value(5), | |
}; | |
assert_eq!( | |
eval(&Expression::Op { | |
op: Operation::Add, | |
left: &term1, | |
right: &term2, | |
}), | |
85 | |
); | |
} | |
#[test] | |
fn test_zeros() { | |
assert_eq!( | |
eval(&Expression::Op { | |
op: Operation::Add, | |
left: &Expression::Value(0), | |
right: &Expression::Value(0) | |
}), | |
0 | |
); | |
assert_eq!( | |
eval(&Expression::Op { | |
op: Operation::Mul, | |
left: &Expression::Value(0), | |
right: &Expression::Value(0) | |
}), | |
0 | |
); | |
assert_eq!( | |
eval(&Expression::Op { | |
op: Operation::Sub, | |
left: &Expression::Value(0), | |
right: &Expression::Value(0) | |
}), | |
0 | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Animal { | |
fn leg_count(&self) -> u32; | |
} | |
trait Pet: Animal { | |
fn name(&self) -> String; | |
} | |
struct Dog(String); | |
impl Pet for Dog { | |
fn name(&self) -> String { | |
self.0.clone() | |
} | |
} | |
impl Animal for Dog { | |
fn leg_count(&self) -> u32 { | |
4 | |
} | |
} | |
struct GoldenRetriever(Dog); | |
macro_rules! inherit_pet_traits { | |
($ty:path) => { | |
impl Animal for $ty { | |
fn leg_count(&self) -> u32 { | |
self.0.leg_count() | |
} | |
} | |
impl Pet for $ty { | |
fn name(&self) -> String { | |
self.0.name() | |
} | |
} | |
}; | |
} | |
inherit_pet_traits!(GoldenRetriever); | |
fn main() { | |
let puppy = Dog(String::from("Rex")); | |
println!("{} has {} legs", puppy.name(), puppy.leg_count()); | |
let retriever = GoldenRetriever(Dog("Furry".into())); | |
println!("{}", retriever.name()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment