From 1c5f02be0189e905965395c2083ee5dab5fb71ff Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Mon, 18 May 2020 16:08:16 -0700 Subject: rust learning notes --- software/rust.page | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/software/rust.page b/software/rust.page index 4e8aa44..dc900c8 100644 --- a/software/rust.page +++ b/software/rust.page @@ -60,3 +60,76 @@ Should use match in this case: }, }; +## 2020-05-17 Reading + +While working on fatcat-cli tool, checked the The Rust Programming Language +book to read about trait objects and the `dyn` keyword, which I had ignored +previously. + +They seem like they could be used in a few places in fatcat-server rust code. +We don't particularly care about per-function-call performance there, and most +entities are already allocated on the heap. + +Other small syntax and thing learned: + +Can copy a struct while only updating specific fields with ".." syntax. Might +use this in fatcat-cli for update mutation. + +This is the cleanest example of using ErrorKind that I have seen: + + let f = match f { + Ok(file) => file, + Err(error) => match error.kind() { + ErrorKind::NotFound => match File::create("hello.txt") { + Ok(fc) => fc, + Err(e) => panic!("Problem creating the file: {:?}", e), + }, + other_error => { + panic!("Problem opening the file: {:?}", other_error) + } + }, + }; + +I didn't realize that test code may get compiled into non-test binaries unless +annotated with `#[cfg(test)]`. You are supposed to create a sub-module within +each `src/` file with unittests, like: + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } + } +This doesn't apply to `tests/` directory, which is for integration tests. + +The common pattern for binary crates (vs. library crates) is to have `main.rs` +and `lib.rs`, with any code that needs to be tested in `lib.rs` (aka, all the +actual logic). + +I think I knew `eprintln!()` (for stderr) vs. `println!()` (for stdout), but +good to remember. + +There is a description of how to avoid memory leaks with reference counting +using "weak" `Rc` references. Probably worth reading the [entire chapter on smart pointers](https://doc.rust-lang.org/book/ch15-06-reference-cycles.html#preventing-reference-cycles-turning-an-rct-into-a-weakt) +(including Box, Rc, RefCell) again. + +For the `Sized` trait, and `Sized` trait alone, can specify an ambiguous trait +constraint with `?` to indicate "may or may not be Sized", which doesn't really +mean anything but does explicitly allow generic functions over non-sized traits +like: + + fn my_generic_func(t: &T) { + // --snip-- + } + +A trait can depend on another trait. For example, a PrettyPrint trait could +rely on Display (and impl functions could call functions from Display). This is +done on the trait definition line. Such a trait is called a "supertrait". + +Implementing Deref on a wrapper type allows transparent access to all the trait +methods on the interior object. + +Also, a new longer post on error handling: -- cgit v1.2.3