The End of the Tour
2026-09-10
README.md and files are updatedkeys.rsanagrams.rs and keys.rs
tests/keys_test.rscrate file for P2
rs files will not work!Performance of single-thread codes, requiring
Two weeks:
What’s familiar from C/C++/Java?
What’s familiar from functional languages?
matchWhat’s unfamiliar? Ownership and borrowing.
Also maybe error handling with Result? Macros?
Stated module goals:
But:
Okay, on to some remaining topics…
lib.rs or main.rsboots::cats says to look in src/boots/cats.rssuper points to parent moduleself points to current moduleuse brings a name into current space (pub use re-exports)trait Hello { fn speak(&self); }
struct Dog { name: &'static str }
struct Cat { name: &'static str }
impl Hello for Dog {
fn speak(&self) { println!("{} says woof!", self.name); }
}
impl Hello for Cat {
fn speak(&self) { println!("{} stares aloofly", self.name); }
}
fn speak_to(who: &dyn Hello) { who.speak(); }
fn main() {
speak_to(&Dog {name: "Fido"});
speak_to(&Cat {name: "Pete"});
}(ptr, vtable ptr)dropdyn Trait interfaces must be type generic
SelfDynamically sized type examples:
strSize is not known at compile time.
Sized and ?SizedTwo special trait bounds:
Sized when size is known at compile time
std::mem::size_of::<T>() for Sized types?Sized when unknown size is allowedType parameters and associated types are Sized unless explicitly declared ?Sized
An idiom is a common code pattern
GithubId, Password, and String are now different typespub fn lookup_user(user: &GithubId) -> Result<UserRecord, GithubId> {
//...
}
pub fn validate_password(user_rec: UserRecord, password: &Password)
-> Result<(), PasswordError> {
//...
}
pub fn login(user: &GithubId, password: Password)
-> Result<Session, LoginError> {
let user_info = lookup_user(user);
validate_password(user_info, &password)?;
//...
}Five additional actions:
unionNot a free-for-all!
unsafe code is scoped (use in small doses)For more see the Rustonomicon
Basic rules
… with addenda for smart pointers (esp RefCell)
Good examples in Rust By Example!
Rust generics parameterize over types, constants
fn mymax<T,Titer>(mut t: Titer) -> Option<T>
where
T: Ord,
Titer: Iterator<Item=T>
{
let Some(item) = t.next() else { return None; };
let mut max_item = item;
for item in t {
if item > max_item {
max_item = item;
}
}
Some(max_item)
}
fn main() {
let v = vec![1, 2, 2, 1];
println!("{:?}", mymax(v.iter()));
}Basic idea: T: S + R for traits S and R means
T must implement S and RT requires S and R
S and R are supertraits of TAgain, Rust by Example has great examples!
What are your thoughts on course logistics?
Constructive feedback would be great!