sigh, I'm going to need stronger drugz to walk my way through this "example":
----- snip -----
use std::fmt::Display;
fn longest_with_an_announcement<'a, T>(
x: &'a str,
y: &'a str,
ann: T,
) -> &'a str
where
T: Display,
{
println!("Announcement! {}", ann);
if x.len() > y.len() {
x
} else {
y
}
}
----- snip -----
#LearningRust
master of understatement:
"Most of the time, an error message suggesting the 'static lifetime results from attempting to create a dangling reference or a mismatch of the available lifetimes. In such cases, the solution is fixing those problems, not specifying the 'static lifetime."
translation: if you have to use a shotgun, then you are probably doing something wrong.
hmmmm, going to have to re-read "10.3. Validating References with Lifetimes" a few more times to grok it. in the first example set, the problem lifetimes is aimed at solving looks to me like an artifact of the language avoiding using an explicit return statement.
either I am missing something and later sections of this chapter will clarify, or this is really just a way to overcome a logical ambiguity problem which the language itself has introduced.
"Note that it isn’t possible to call the default implementation from an overriding implementation of that same method."
traits ain't interfaces, in the OOP sense... no calling "super"
hmmm, "traits" are pretty sweet... and subtly different than "interfaces"c
reading: "Traits: Defining Shared Behavior"
ugh, I understand why they re-used names in the example-set code and... ugh. Phil Karlton wuz right.
moving on to CH 10: "Generic Types, Traits, and Lifetimes"
giant machines are attacking the pavement outside... <sigh/> 🚜
it must be time for a break
okay, this is sweet:
"Re-exporting is useful when the internal structure of your code is different from how programmers calling your code would think about the domain... With pub use, we can write our code with one structure but expose a different structure. Doing so makes our library well organized for programmers working on the library and programmers calling the library. "
eminently sensible:
"If we use pub before a struct definition, we make the struct public, but the struct’s fields will still be private. We can make each field public or not on a case-by-case basis... if we make an enum public, all of its variants are then public. We only need the pub before the enum keyword"
okay, this makes a lot of sense to me as a project pattern:
"...a package can contain both a src/main.rs binary crate root as well as a src/lib.rs library crate root, and both crates will have the package name by default. Typically, packages with this pattern of containing both a library and a binary crate will have just enough code in the binary crate to start an executable that calls code with the library crate...
The module tree should be defined in src/lib.rs. Then, any public items can be used in the binary crate by starting paths with the name of the package. The binary crate becomes a user of the library crate just like a completely external crate would use the library crate: it can only use the public API. This helps you design a good API"
reviewing https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html again... the details of a complex project can kill ya, so best to pay attention from the gety-go
https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html
I am curious if experienced Rust programmers find the first approach or the second more comfortable:
----- snip -----
fn file_test() {
let greeting_file_result1 = File::open("hello1.txt");
let greeting_file1 = match greeting_file_result1 {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
//
// versus
//
let greeting_file2 = match File::open("hello2.txt") {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}
----- snip -----
thanks in advance for any comments on advantages of one over the other
day-am... HashMap has sone *dynamite* convenience methods
powerful/dangerous ;^}
#LearningRust
-----
"pub fn drain(&mut self) -> Drain<'_, K, V> ⓘ
Clears the map, returning all key-value pairs as an iterator. Keeps the allocated memory for reuse.
If the returned iterator is dropped before being fully consumed, it drops the remaining key-value pairs. The returned iterator keeps a mutable borrow on the map to optimize its implementation."
which style do you prefer, define-at-declaration or define-at-first-use?
okay, no direct indexing into UTF-8, fine by me... UTF-8 can break your brain if you ever reeeeeealy dive into it. (not recommended, religious wars &etc are best avoided)
all my experience says the subtitle "Strings Are Not So Simple" is Totally Correct, so I can certainly live with depending upon the std library for screwing around with String data. no problemo.