Skip to content

Commit dbddad8

Browse files
committed
add ch13 and some ch14 notes
1 parent a58e78c commit dbddad8

File tree

4 files changed

+67
-29
lines changed

4 files changed

+67
-29
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ This repo contains notes from my learnings about the Rust programming language.
44

55
- notes from
66
- [Rust in Motion](https://www.manning.com/livevideo/rust-in-motion)
7-
- [The book](https://doc.rust-lang.org/book/ch05-00-structs.html) (chapters 1-12, inclusive)
7+
- [The book](https://doc.rust-lang.org/book/ch05-00-structs.html) (chapters 1-13, inclusive)
88
- beginner projects from "the book"
99
- coding challenges

notes/rust-lang book/rust-lang-book-notes.md

+47-9
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,7 @@ fn makes_copy(some_integer: i32) {// some_integer comes into scope
242242

243243
- returning values can also transfer ownership; assigning a value to another variable moves it
244244
- when a variable that includes data on the heap goes out of scope, the value will be cleaned up by `drop` unless the data has been moved to be owned by another variable
245-
-
246-
247-
**4.2 References and Borrowing**
245+
- **4.2 References and Borrowing**
248246

249247
- `&` = references, allow you to refer to some value without taking ownership of it
250248
- rules of references - at any given time, you can have _either_ one mutable reference _or_ any number of immutable references - references must always be valid
@@ -975,11 +973,9 @@ fn expensive_test() {
975973
- iterators produce a series of values,
976974
- `collect`: turns iterator into a collection that contains all elements
977975
- needs to have annotation because Rust isn't able to infer collection type
978-
-
976+
- **12.2 Reading a File**
979977

980-
**12.2 Reading a File**
981-
982-
**12.3 Refactoring to Improve Modularity and Error Handling**
978+
**12.3 Refactoring to Improve Modularity and Error Handling**
983979

984980
- primitive obsession: anti pattern where using primitive values when a complex type would be more appropriate
985981
- `unwrap_or_else`: allows to define some custom, non-`panic!` error handling.
@@ -1018,6 +1014,7 @@ fn expensive_test() {
10181014
- explicit type annotations on parameters and functions not required, because closures are usually short and relevant only within a narrow context rather tan in any arbitrary scenario
10191015
- unlike function, can capture their environment and can access variables from the scope in which they're defined
10201016
- when a closure captures a value from it's environment, it uses memory to store the values for use in the closure body
1017+
-
10211018
- closures can capture values from their environment in three ways, which directly map to the three ways a function can take a parameter: taking ownership , borrowing mutably, and borrowing immutably
10221019
- associated traits:
10231020
- `FnOnce`: taking ownership
@@ -1036,10 +1033,51 @@ let expensive_closure = |num| {
10361033
```
10371034

10381035
- reason for using closure: defined the code to call at one point, store that code, and call it at a later point
1039-
-
1036+
- **13.2 Processing a Series of Items with iterators**
1037+
1038+
- iterator
1039+
- responsible for the logic of iterating over each item and determining when the sequence has finished
1040+
- lazy: they have no effect until you call methods that consume the iterator to use it up
1041+
1042+
```rust
1043+
let v1 = vec![10, 20, 30];
1044+
for val in v1_iter {
1045+
println!("val is {} ", val);
1046+
}
1047+
// will print
1048+
// val is 10
1049+
// val is 20
1050+
// val is 30
1051+
```
10401052

1041-
**13.2 Processing a Series of Items with iterators**
1053+
- all iterators implement the `Iterator` trait (in standard library)
1054+
- if using the `next` method from `Iterator`, the data structure you're calling it on must be mutable
1055+
- `next` method changes the internal state that the iterator uses to keep track of where it is in the sequence
1056+
- methods that call `next` are called _consuming adaptors_, because calling them uses up the iterator
1057+
- _iterator adaptors_: allow you to change iterators into different kinds of iterators
1058+
- `collect`: consumes the iterator and collects the resulting values into a collection data type
1059+
1060+
```rust
1061+
let v1: Vec<i32> =vec![1, 2, 3];
1062+
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
1063+
```
10421064

10431065
**13.3 Improving Our I/O Project**
10441066

10451067
**13.4 Comparing Performance: Loops vs Iterators**
1068+
1069+
- iterators get compiled down to roughly the same code as if you'd written the lower-level code yourself
1070+
- Iterators are one of Rust’s _zero-cost abstractions_, by which we mean using the abstraction imposes no additional runtime overhead.
1071+
- _Unrolling_: optimization that removes the overhead of the loop controlling code and instead generates repetitive code for each iteration of the loop.
1072+
1073+
### Chapter 14 - More About Cargo and Crates.io
1074+
1075+
- **14.1 Customizing Builds with Release Profiles**
1076+
1077+
**14.2 Publishing a Crate to Crates.io**
1078+
1079+
**14.3 Cargo Workspaces**
1080+
1081+
**14.4 Installing Binaries from Crates.io with cargo install**
1082+
1083+
**14.5 Extending Cargo with Custom Commands**

rust-lang-book/projects/minigrep/src/lib.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,19 @@ impl Config {
2828
// returns Result
2929
// Config in success case
3030
// &str in error case
31-
pub fn new(args: &[String]) -> Result<Config, &str> {
32-
if args.len() < 3 {
33-
return Err("not enough arguments");
34-
}
35-
let query = args[1].clone();
36-
let filename = args[2].clone();
31+
pub fn new(mut args: env::Args) -> Result<Config, &'static str> {
32+
args.next();
33+
34+
let query = match args.next() {
35+
Some(arg) => arg,
36+
None => return Err("Didn't get a query string"),
37+
};
38+
39+
let filename = match args.next() {
40+
Some(arg) => arg,
41+
None => return Err("Didn't get a file name"),
42+
};
43+
3744
let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
3845

3946
Ok(Config {
@@ -45,15 +52,10 @@ impl Config {
4552
}
4653

4754
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
48-
let mut results = Vec::new();
49-
50-
for line in contents.lines() {
51-
if line.contains(query) {
52-
results.push(line);
53-
}
54-
}
55-
56-
results
55+
contents
56+
.lines()
57+
.filter(|line| line.contains(query))
58+
.collect()
5759
}
5860

5961
pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {

rust-lang-book/projects/minigrep/src/main.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ use std::process;
44
use minigrep::Config;
55

66
fn main() {
7-
let args: Vec<String> = env::args().collect();
8-
9-
let config = Config::new(&args).unwrap_or_else(|err| {
10-
eprintln!("Problem passing arguments: {}", err);
7+
let config = Config::new(env::args()).unwrap_or_else(|err| {
8+
eprintln!("Problem parsing arguments: {}", err);
119
process::exit(1);
1210
});
1311

0 commit comments

Comments
 (0)