Skip to content

Instantly share code, notes, and snippets.

@sffc
Created February 12, 2025 09:24
Show Gist options
  • Save sffc/9eb7a74de36d3baca3b58196f253169d to your computer and use it in GitHub Desktop.
Save sffc/9eb7a74de36d3baca3b58196f253169d to your computer and use it in GitHub Desktop.
Examples from Comprehensive Rust @ University of Bergen, January 2025
#[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:?}");
}
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());
}
#[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);
/// 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
);
}
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