Download as pdf or txt
Download as pdf or txt
You are on page 1of 11

‭version 1.0.

7‬

‭Table of Contents‬

‭Basic Types & Variables‬


‭Control Flow‬
‭References, Ownership, and Borrowing‬
‭Pattern Matching‬
‭Iterators‬
‭Error Handling‬
‭Combinators‬
‭Multiple error types‬
‭Iterating over errors‬
‭Generics, Traits, and Lifetimes‬
‭Functions, Function Pointers & Closures‬
‭Pointers‬
‭Smart pointers‬
‭Packages, Crates, and Modules‬

‭YouTube Channel:‬‭https://www.youtube.com/c/LetsGetRusty‬
‭Basic Types & Variables‬ ‭Struct‬
‭/ Definition‬
/
‭bool‬‭- Boolean‬
struct‬‭
‭ User‬‭
{‬
username:‬‭
‭ String‬
,‬

‭ nsigned integers‬
U
active:‬‭
‭ bool‬,‬

‭u8‬‭,‬‭u16‬‭,‬‭u32‬‭,‬‭u64‬‭,‬‭u128‬
}‬

‭ igned integers‬
S
‭/ Instantiation‬
/
‭i8‬‭,‬‭i16‬‭,‬‭i32‬‭,‬‭i64‬‭,‬‭i128‬
let‬‭
‭ user1 = User {‬
username:‬‭
‭ String‬
::from(‬
‭ "bogdan"‬
‭ ),‬

‭ loating point numbers‬
F
active:‬‭
‭ true‬
,‬

‭f32‬‭,‬‭f64‬
};‬

‭ latform specific integers‬


P
‭/ Tuple struct‬
/
‭usize‬‭- Unsigned integer. Same number of bits as the‬
struct‬‭
‭ Color‬
(‭
‭i
‬32‬
,‬‭
‭ i32‬,‬‭
‭ i32‬);‬

‭platform's pointer type.‬
let‬‭
‭ black = Color(‬
0‭
‭ ,
‬‬‭
0‬,‬‭
‭ 0‭
)
‬;‬

i‭size‬‭- Signed integer. Same number of bits as the‬


‭platform's pointer type.‬ ‭Enum‬
‭/ Definition‬
/
‭ har‬‭-‬‭Unicode scalar value‬
c enum‬‭
‭ Command‬‭
{‬
‭&str‬‭- String slice‬ Quit,‬

‭String‬‭- Owned string‬ Move { x:‬‭
‭ i32‬, y:‬‭
‭ i32‬‭
},‬
Speak(‬
‭ String‬
‭ ),‬

‭Tuple‬ ChangeBGColor(‬
‭ i32‬
‭ ,‬‭
‭ i32‬
,‬‭
‭ i32‬
),‬

‭et‬‭
l coordinates = (‬
82‬
‭ ,‬‭
‭ 64‬
);‬
‭ }‬

let‬‭
‭ score = (‬
"Team A"‬
‭ ,‬‭
‭ 12‬
)‬

‭/ Instantiation‬
/
let‬‭
‭ msg1 = Command::Quit;‬
‭Array & Slice‬
let‬‭
‭ msg2 = Command::Move{ x:‬‭1‬
, y:‬‭
‭ 2‬‭
};‬
‭/ Arrays must have a known length and all‬
/ let‬‭
‭ msg3 = Command::Speak(‬"Hi"‬
‭ .to_owned());‬

elements must be initialized‬
‭ let‬‭
‭ msg4 = Command::ChangeBGColor(‬0‭
‭,
‬‬‭
0‬,‬‭
‭ 0‭
)
‬;‬
let‬‭
‭ array = [‬
1‭
‭,
‬‬‭
2‬,‬‭
‭ 3‭
,
‬‬‭4‬
,‬‭
‭ 5‭
]
‬;‬
let‬‭
‭ array2 = [‬
0‬
‭;‬‭
‭ 3‭
]
‬;‬‭ // [0, 0, 0]‬
‭Constant‬

‭/ Unlike arrays the length of a slice is‬


/ const‬‭
‭ MAX_POINTS:‬‭
u32‬‭
=‬‭
100_000‬
;‬

determined at runtime‬

let‬‭
‭ slice = &array[‬
1‬‭
‭ ..‬‭
3‬];‬
‭ ‭Static variable‬
‭/ Unlike constants static variables are‬
/
‭HashMap‬ // stored in a dedicated memory location‬

use‬‭
‭ std::collections::HashMap;‬ // and can be mutated.‬

static‬‭
‭ MAJOR_VERSION:‬‭
u32‬‭
=‬‭
1‭
;
‬‬
‭et‬‭
l mut‬‭
subs = HashMap::new();‬ static‬‭
‭ mut‬‭
COUNTER:‬‭
u32‬‭
=‬‭
0‭
;
‬‬
subs.insert(‬
‭ String‬
‭ ::from(‬
‭ "LGR"‬
‭ ),‬‭
‭ 100000‬
);‬

// Insert key if it doesn't have a value‬

subs.entry(‬
‭ "Golang Dojo"‬
‭ .to_owned())‬

.or_insert(‬
‭ 3‬
‭ );‬

‭Mutability‬ ‭Returning from loops‬
‭et‬‭
l mut‬‭
x =‬‭
5‬
;‬
‭ let‬‭
‭ mut‬‭
counter =‬‭
0‭
;
‬‬
x =‬‭
‭ 6‭
;
‬‬
let‬‭
‭ result =‬‭
loop‬‭
{‬
‭Shadowing‬ counter +=‬‭
‭ 1‬;‬

‭et‬‭
l x =‬‭
5‬
;‬
‭ if‬‭
‭ counter ==‬‭
10‬‭{‬
let‬‭
‭ x = x *‬‭
2‬
;‬
‭ break‬‭
‭ counter;‬
}‬

‭Type alias‬ };‬

‭/ `NanoSecond` is a new name for `u64`.‬
/
type‬‭
‭ NanoSecond‬‭
=‬‭
u64‬
;‬
‭ ‭while and while let‬
while‬‭
‭ n <‬‭101‬‭
{‬
‭Control Flow‬ n +=‬‭
‭ 1‭
;
‬‬
}‬

‭if and if let‬
let‬‭
‭ num =‬‭
Some‬
(‬
‭22‬
‭ );‬
‭ let‬‭
‭ mut‬‭
optional =‬‭
Some‬
(‭
‭0
‬‭
)
‬;‬

if‬‭
‭ num.is_some() {‬ while‬‭
‭ let‬‭Some‬(i) = optional {‬

println!‬
‭ (‬
‭ "number is: {}"‬
‭ , num.unwrap());‬
‭ print!‬
‭ (‬
‭ "{}"‬
‭ , i);‬

}‬
‭ }‬

‭/ match pattern and assign variable‬


/ ‭for loop‬
if‬‭
‭ let‬‭
Some‬(i) = num {‬

println!‬
‭ (‬
‭ "number is: {}"‬
‭ , i);‬
‭ for‬‭
‭ n‬‭
in‬‭
1‭
.
‬.‬101‬‭
‭ {‬
}‬
‭ println!‬
‭ (‬
‭ "{}"‬
‭ , n);‬

}‬

‭loop‬ let‬‭
‭ names =‬‭
vec!‬
[‭
‭"
‬Bogdan"‬
,‬‭
‭ "Wallace"‬
];‬

‭et‬‭
l mut‬‭
count =‬‭
0‬;‬

loop‬‭
‭ {‬ for‬‭
‭ name‬‭
in‬‭names.iter() {‬
count +=‬‭
‭ 1‬
;‬
‭ println!‬
‭ (‬
‭ "{}"‬
‭ , name);‬

if‬‭
‭ count ==‬‭
5‬‭
{‬ }‬

break‬
‭ ;‬‭
‭ // Exit loop‬
}‬
‭ ‭match‬
}‬

let‬‭
‭ optional =‬‭
Some‬
(‭
‭0
‬‭
)
‬;‬

‭Nested loops & labels‬ match‬‭


‭ optional {‬
'outer‬
‭ :‬‭
‭ loop‬‭
{‬ Some‬
‭ (i) =>‬‭
‭ println!‬(‬
‭ "{}"‬
‭ , i),‬

'inner‬
‭ :‬‭
‭ loop‬‭
{‬ None‬‭
‭ =>‬‭
println!‬
(‭
‭ "
‬No value."‬)‬

// This breaks the inner loop‬
‭ }‬

break‬
‭ ;‬

// This breaks the outer loop‬

break‬‭
‭ 'outer‬
;‬

}‬

}‬

‭ eferences, Ownership, and‬
R ‭Ownership and functions‬

‭Borrowing‬ fn‬‭
‭ main‬
() {‬

let‬‭
‭ x =‬‭
5‬;‬

‭Ownership rules‬ takes_copy(x);‬‭
‭ // x is copied by value‬
‭1.‬ ‭Each value in Rust has a variable that’s called its‬
‭owner.‬ ‭et‬‭
l s =‬‭
String‬
::from(‬
‭ "Let’s Get Rusty!"‬
‭ );‬

‭2.‬ ‭There can only be one owner at a time.‬ // s is moved into the function‬

‭3.‬ ‭When the owner goes out of scope, the value will‬ takes_ownership(s);‬

‭be dropped.‬
‭/ return value is moved into s1‬
/
‭Borrowing rules‬ let‬‭
‭ s1 = gives_ownership();‬
‭1.‬ ‭At any given time, you can have‬‭either‬‭one‬
‭mutable reference‬‭or‬‭any number of immutable‬ ‭et‬‭
l s2 =‬‭
String‬
::from(‬
‭ "LGR"‬
‭ );‬

‭references.‬ let‬‭
‭ s3 = takes_and_gives_back(s2);‬
‭2.‬ ‭References must always be valid.‬ }‬

‭Creating references‬ fn‬‭


‭ takes_copy‬(some_integer:‬‭
‭ i32‬
) {‬

‭et‬‭
l s1 =‬‭
String‬
::from(‬
‭ "hello world!"‬
‭ );‬
‭ println!‬
‭ (‬
‭ "{}"‬
‭ , some_integer);‬

let‬‭
‭ s1_ref = &s1;‬‭
// immutable reference‬ }‬

‭et‬‭
l mut‬‭
s2 =‬‭
String‬::from(‬
‭ "hello"‬
‭ );‬
‭ fn‬‭
‭ takes_ownership‬(some_string:‬‭
‭ String‬
) {‬

let‬‭
‭ s2_ref = &‬
mut‬‭
‭ s2;‬‭// mutable reference‬ println!‬
‭ (‬
‭ "{}"‬
‭ , some_string);‬

}‬‭
‭ // some_string goes out of scope and drop‬
s2_ref.push_str(‬
‭ " world!"‬
‭ );‬
‭ is called. The backing memory is freed.‬

fn‬‭
‭ gives_ownership‬
() ->‬‭
‭ String‬‭
{‬
‭Copy, Move, and Clone‬ let‬‭
‭ some_string =‬‭
String‬
::from(‬
‭ "LGR"‬
‭ );‬

‭/ Simple values which implement the Copy‬
/ some_string‬

trait are copied by value‬
‭ }‬

let‬‭
‭ x =‬‭
5‬
;‬

let‬‭
‭ y = x;‬ ‭n‬‭
f takes_and_gives_back‬
(some_string:‬

String‬
‭ ) ->‬‭
‭ String‬‭
{‬
println!‬
‭ (‬
‭ "{}"‬
‭ , x);‬‭
‭ // x is still valid‬ some_string‬

}‬

‭/ The string is moved to s2 and s1 is‬
/
invalidated‬

let‬‭
‭ s1 =‬‭
String‬
::from(‬
‭ "Let's Get Rusty!"‬
‭ );‬

let‬‭
‭ s2 = s1;‬‭
// Shallow copy a.k.a move‬

println!‬
‭ (‬
‭ "{}"‬
‭ , s1);‬‭
‭ // Error: s1 is invalid‬

‭et‬‭
l s1 =‬‭
String‬
::from(‬
‭ "Let's Get Rusty!"‬
‭ );‬

let‬‭
‭ s2 = s1.clone();‬‭
// Deep copy‬

‭/ Valid because s1 isn't moved‬


/
println!‬
‭ (‬
‭ "{}"‬
‭ , s1);‬

‭Pattern Matching‬ ‭Ignoring values‬
struct‬‭
‭ SemVer‬
(‬
‭ i32‬
‭ ,‬‭
‭ i32‬
,‬‭
‭ i32‬
);‬

‭Basics‬
let‬‭
‭ x =‬‭
5‬
;‬
‭ let‬‭
‭ version = SemVer(‬
1‬
‭ ,‬‭
‭ 32‬
,‬‭
‭ 2‭
)
‬;‬

match‬‭
‭ x {‬ match‬‭
‭ version {‬
// matching literals‬
‭ SemVer(major, _, _) => {‬

1‬‭
‭ =>‬‭
println!‬
(‬
‭"one"‬
‭ ),‬
‭ println!‬
‭ (‭
‭"
‬{}"‬
, major);‬

// matching multiple patterns‬
‭ }‬

2‬‭
‭ |‬‭
3‬‭
=>‬‭
println!‬
(‭
‭"‬two or three"‬
),‬
‭ }‬

// matching ranges‬

4‬
‭..=‬
‭ 9‬‭
‭ =>‬‭
println!‬
(‭
‭"‬within range"‬
),‬
‭ let‬‭
‭ numbers = (‬
2‭
‭,‬‬‭
4‭
,
‬‬‭
8‬,‬‭
‭ 16‬
,‬‭
‭ 32‬
);‬

// matching named variables‬

x =>‬‭
‭ println!‬
(‬
‭"{}"‬
‭ , x),‬
‭ match‬‭
‭ numbers {‬
// default case (ignores value)‬
‭ (first, .., last) => {‬

_ =>‬‭
‭ println!‬
(‬
‭"default Case"‬
‭ )‬
‭ println!‬
‭ (‭
‭"
‬{}, {}"‬
, first, last);‬

}‬
‭ }‬

}‬

‭Destructuring‬
struct‬‭
‭ Point‬‭
{‬ ‭Match guards‬
x:‬‭
‭ i32‬
,‬
‭ let‬‭
‭ num =‬‭
Some‬
(‭
‭ 4
‬‭
)
‬;‬
y:‬‭
‭ i32‬
,‬

}‬
‭ match‬‭
‭ num {‬
Some‬
‭ (x)‬‭
‭ if‬‭
x <‬‭
5‬‭
=>‬‭println!‬
(‭
‭"
‬less than‬
let‬‭
‭ p = Point { x:‬‭
0‭
,
‬ y:‬‭
7‬‭
};‬ five: {}"‬
‭ , x),‬

Some‬
‭ (x) =>‬‭
‭ println!‬
(‬
‭ "{}"‬
‭ , x),‬

match‬‭
‭ p {‬ None‬‭
‭ => (),‬
Point { x, y:‬‭
‭ 0‬‭
} => {‬ }‬

println!‬
‭ (‬
‭"{}"‬‭
‭ , x);‬
},‬

‭@ bindings‬
Point { x, y } => {‬

println!‬
‭ (‬
‭"{} {}"‬‭
‭ , x, y);‬ struct‬‭
‭ User‬‭
{‬
},‬
‭ id:‬‭
‭ i32‬
}‬
‭ }‬

enum‬‭
‭ Shape‬‭
{‬ let‬‭
‭ user = User { id:‬‭
5‬‭
};‬
Rectangle { width:‬‭
‭ i32‬
, height:‬‭
‭ i32‬‭
},‬
Circle(‬
‭ i32‬
‭ ),‬
‭ match‬‭
‭ user {‬
}‬
‭ User {‬

id: id_variable @‬‭
‭ 3‭
.
‬.=‬7‭
‭,
‬‬
let‬‭
‭ shape = Shape::Circle(‬
10‬
‭ );‬
‭ } =>‬‭
‭ println!‬
(‭
‭ "
‬id: {}"‬, id_variable),‬

User { id:‬‭
‭ 10‬
..=‬
‭ 12‬‭
‭ } => {‬
match‬‭
‭ shape {‬ println!‬
‭ (‭
‭"
‬within range"‬ );‬

Shape::Rectangle { x, y } =>‬‭
‭ //...‬ },‬

Shape::Circle(radius) =>‬‭
‭ //...‬ User { id } =>‬‭
‭ println!‬(‬
‭ "id: {}"‬
‭ , id),‬

}‬
‭ }‬

‭Iterators‬ ‭Error Handling‬
‭Usage‬ ‭Throw unrecoverable error‬
‭/ Methods that consume iterators‬
/ panic!‬
‭ (‬
‭ "Critical error! Exiting!"‬
‭ );‬

let‬‭
‭ v1 =‬‭
vec!‬
[‭
‭1
‬‬
,‬‭
‭ 2‭
,
‬‬‭
3‬];‬

let‬‭
‭ v1_iter = v1.iter();‬ ‭Option enum‬
let‬‭
‭ total:‬‭
i32‬‭
= v1_iter.sum();‬
fn‬‭
‭ get_user_id‬(name: &‬
‭ str‬
‭ ) ->‬‭
‭ Option‬
<‭
‭u
‬32‬
> {‬

‭/ Methods that produce new iterators‬
/ if‬‭
‭ database.user_exists(name) {‬
let‬‭
‭ v1:‬‭
Vec‬
<‬
‭i32‬
‭ > =‬‭
‭ vec!‬
[‭
‭1
‬‬,‬‭
‭ 2‭
,
‬‬‭
3‬];‬
‭ return‬‭
‭ Some‬
(database.get_id(name))‬

let‬‭
‭ iter = v1.iter().map(|x| x +‬‭ 1‭
)
‬;‬ }‬

‭/ Turning iterators into a collection‬


/ None‬

let‬‭
‭ v1:‬‭
Vec‬
<‬
‭i32‬
‭ > =‬‭
‭ vec!‬
[‭
‭1
‬‬,‬‭
‭ 2‭
,
‬‬‭
3‬];‬
‭ }‬

let‬‭
‭ v2:‬‭
Vec‬
<_> = v1.iter().map(|x| x +‬

1‬
‭).collect();‬
‭ ‭Result enum‬
‭n‬‭
f get_user‬(id:‬‭
‭ u32‬
) ->‬‭
‭ Result‬
<User, Error>‬

‭Implementing the Iterator trait‬ {‬

struct‬‭
‭ Counter‬‭
{‬ if‬‭
‭ is_logged_in_as(id) {‬
count:‬‭
‭ u32‬
,‬
‭ return‬‭
‭ Ok‬
(get_user_object(id))‬

}‬
‭ }‬

impl‬‭
‭ Counter {‬ Err‬
‭ (Error { msg:‬‭
‭ "not logged in"‬‭
})‬
fn‬‭
‭ new‬
() -> Counter {‬
‭ }‬

Counter { count:‬‭
‭ 0‬‭
}‬
}‬
‭ ‭? operator‬
}‬

‭n‬‭
f get_salary‬(db: Database, id:‬‭
‭ i32‬
) ->‬

Option‬
‭ <‬
‭ u32‬
‭ > {‬

impl‬‭
‭ Iterator‬‭
for‬‭
Counter {‬
Some‬
‭ (db.get_user(id)?.get_job()?.salary)‬

type‬‭
‭ Item‬‭
=‬‭
u32‬
;‬

}‬

‭n‬‭
f next‬
(&‬
‭ mut‬‭
‭ self‬
) ->‬‭
‭ Option‬
<Self::Item>‬

‭n‬‭
f connect‬
(db: Database) ->‬

{‬

Result‬
‭ <Connection, Error> {‬

if‬‭
‭ self‬
.count <‬‭
‭ 5‬‭{‬
let‬‭
‭ conn =‬
self‬
‭ .count +=‬‭
‭ 1‬;‬

db.get_active_instance()?.connect()?;‬

Some‬
‭ (‬
‭self‬
‭ .count)‬

Ok‬
‭ (conn)‬

}‬‭
‭ else‬‭
{‬
}‬

None‬

}‬

}‬

}‬

‭Combinators‬ ‭Boxing errors‬

‭.map‬ use‬‭
‭ std::error;‬

let‬‭
‭ some_string =‬‭
Some‬
(‬
‭ "LGR"‬
‭ .to_owned());‬

‭ype‬‭
t Result‬
<T> = std::result::‬
‭ Result‬
‭ <T,‬

Box‬
‭ <dyn error::Error>>;‬

‭et‬‭
l some_len = some_string.map(|s|‬
s.len());‬

‭Iterating over errors‬
‭truct‬‭
s Error‬‭
{ msg:‬‭
String‬‭
}‬ ‭Ignore failed items with filter_map()‬
struct‬‭
‭ User‬‭
{ name:‬‭
String‬‭
}‬
‭et‬‭
l strings =‬‭vec!‬
[‭
‭"
‬LGR"‬
,‬‭
‭ "22"‬,‬‭
‭ "7"‬
];‬

let‬‭
‭ numbers:‬‭
Vec‬<_> = strings‬

‭et‬‭
l string_result:‬‭
Result‬<‭
‭S
‬tring‬
, Error> =‬

.into_iter()‬

Ok‬
‭ (‬
‭"Bogdan"‬
‭ .to_owned());‬

.filter_map(|s| s.parse::<‬
‭ i32‬
‭ >().ok())‬

.collect();‬

let‬‭
‭ user_result:‬‭
Result‬
<User, Error> =‬

string_result.map(|name| {‬

User { name }‬
‭ ‭Fail the entire operation with collect()‬
});‬
‭ let‬‭
‭ strings =‬‭
vec!‬
[‭
‭"
‬LGR"‬
,‬‭
‭ "22"‬
,‬‭
‭ "7"‬
];‬

‭.and_then‬ let‬‭
‭ numbers:‬‭
Result‬
<‭
‭ V
‬ec‬
<_>, _> = strings‬

.into_iter()‬

‭et‬‭
l vec =‬‭
Some‬
(‬
‭vec!‬
‭ [‭
‭1‬‬
,‬‭
‭ 2‭
,
‬‬‭
3‬]);‬

.map(|s| s.parse::<‬
‭ i32‬
‭ >())‬

let‬‭
‭ first_element = vec.and_then(‬
.collect();‬

|vec| vec.into_iter().next()‬

);‬

‭Collect all valid values and failures with partition()‬
‭et‬‭
l string_result:‬‭
Result‬
<&‬
‭ 'static‬‭
‭ str‬
, _>‬
‭ let‬‭
‭ strings =‬‭
vec!‬
[‭
‭"
‬LGR"‬
,‬‭
‭ "22"‬
,‬‭
‭ "7"‬
];‬

=‬‭
‭ Ok‬
(‭
‭ "
‬5"‬
);‬

let‬‭
‭ number_result =‬ ‭et‬‭
l (numbers, errors): (‬
Vec‬
‭ <_>,‬‭
‭ Vec‬
<_>) =‬

string_result‬
‭ strings‬

.and_then(|s| s.parse::<‬
‭ u32‬
‭ >());‬
‭ .into_iter()‬

.map(|s| s.parse::<‬
‭ i32‬
‭ >())‬

‭Multiple error types‬ .partition(‬
‭ Result‬
‭ ::is_ok);‬

‭Define custom error type‬


let‬‭
‭ numbers:‬‭
Vec‬
<_> = numbers‬

‭ype‬‭
t Result‬
<T> = std::result::‬
‭ Result‬
‭ <T,‬
‭ .into_iter()‬

CustomError>;‬
‭ .map(‬
‭ Result‬
‭ ::unwrap)‬

.collect();‬

‭[derive(Debug, Clone)]‬
#
struct‬‭
‭ CustomError‬
;‬
‭ let‬‭
‭ errors:‬‭
Vec‬<_> = errors‬

.into_iter()‬

impl‬‭
‭ fmt::Display‬‭
for‬‭
CustomError {‬ .map(‬
‭ Result‬
‭ ::unwrap_err)‬

fn‬‭
‭ fmt‬
(&‬
‭ self‬
‭ , f: &‬
‭ mut‬‭
‭ fmt::Formatter) ->‬ .collect();‬

fmt::‬
‭ Result‬‭
‭ {‬
write!‬
‭ (f,‬‭
‭ "custom error message"‬
)‬

}‬

}‬

‭Generics, Traits, and Lifetimes‬ ‭Trait bounds‬
‭n‬‭
f largest‬
<T:‬‭
‭ PartialOrd‬‭
+‬‭Copy‬
>(list:‬

‭Using generics‬
&[T]) -> T {‬

struct‬‭
‭ Point‬
<T, U> {‬
‭ let‬‭
‭ mut‬‭
largest = list[‬
0‬
‭ ];‬

x: T,‬

y: U,‬
‭ for‬‭
‭ &item‬‭in‬‭
list {‬
}‬
‭ if‬‭
‭ item > largest {‬
largest = item;‬

impl‬
‭ <T, U> Point<T, U> {‬
‭ }‬

fn‬‭
‭ mixup‬
<V, W>(‬
‭ self‬
‭ , other: Point<V, W>)‬
‭ }‬

-> Point<T, W> {‬

Point {‬
‭ ‭argest‬
l
x:‬‭
‭ self‬
.x,‬
‭ }‬

y: other.y,‬

}‬

‭impl trait‬
}‬

}‬
‭ ‭n‬‭
f make_adder_function‬(y:‬‭
‭ i32‬
) ->‬‭
‭ impl‬
Fn‬
‭ (‬
‭ i32‬
‭ ) ->‬‭
‭ i32‬‭
{‬
let‬‭
‭ closure =‬‭
move‬‭
|x:‬‭i32‬
| { x + y };‬

‭Defining traits‬
closure‬

trait‬‭
‭ Animal‬‭
{‬ }‬

fn‬‭
‭ new‬
(name: &‬
‭ 'static‬‭
‭ str‬
) ->‬‭
‭ Self‬
;‬

fn‬‭
‭ noise‬
(&‬
‭ self‬
‭ ) -> &‬
‭ 'static‬‭
‭ str‬‭
{‬‭
""‬‭
}‬
‭Trait objects‬
}‬

pub‬‭
‭ struct‬‭
Screen‬‭
{‬
struct‬‭
‭ Dog‬‭
{ name: &‬
'static‬‭
‭ str‬‭
}‬ pub‬‭
‭ components:‬‭
Vec‬
<‬
‭ Box‬
‭ <dyn Draw>>,‬

}‬

impl‬‭
‭ Dog {‬
fn‬‭
‭ fetch‬
() {‬‭
‭ // ...‬‭
}‬ ‭Operator overloading‬
}‬

use‬‭
‭ std::ops::Add;‬
impl‬‭
‭ Animal‬‭
for‬‭
Dog {‬
‭[derive(Debug, Copy, Clone, PartialEq)]‬
#
fn‬‭
‭ new‬
(name: &‬
‭ 'static‬‭
‭ str‬
) -> Dog {‬

struct‬‭
‭ Point‬‭
{‬
Dog { name: name }‬

x:‬‭
‭ i32‬
,‬

}‬

y:‬‭
‭ i32‬
,‬

}‬

fn‬‭
‭ noise‬
(&‬
‭ self‬
‭ ) -> &‬
‭ 'static‬‭
‭ str‬‭
{‬
"woof!"‬

impl‬‭
‭ Add‬‭
for‬‭
Point {‬
}‬

type‬‭
‭ Output‬‭= Point;‬
}‬

fn‬‭
‭ add‬
(‬
‭ self‬
‭ , other: Point) -> Point {‬

‭Default implementations with Derive‬ Point {‬

‭/ A tuple struct that can be printed‬
/ x:‬‭
‭ self‬
.x + other.x,‬

#[derive(Debug)]‬
‭ y:‬‭
‭ self‬
.y + other.y,‬

struct‬‭
‭ Inches‬
(‭
‭i
‬32‬);‬
‭ }‬

}‬

}‬

‭Supertraits‬ ‭Function pointers‬
use‬‭
‭ std::fmt;‬ ‭n‬‭
f do_twice‬
(f:‬‭
‭ fn‬
(‬
‭ i32‬
‭ ) ->‬‭
‭ i32‬
, arg:‬‭
‭ i32‬
) ->‬

i32‬‭
‭ {‬
trait‬‭
‭ Log‬
: fmt::Display {‬
‭ f(arg) + f(arg)‬

fn‬‭
‭ log‬
(&‬
‭ self‬
‭ ) {‬
‭ }‬

let‬‭
‭ output =‬‭
self‬
.to_string();‬

println!‬
‭ (‬
‭"Logging: {}"‬
‭ , output);‬
‭ ‭Creating closures‬
}‬

}‬
‭ let‬‭
‭ add_one = |num:‬‭
u32‬
| ->‬‭
‭ u32‬‭
{‬
num +‬‭
‭ 1‬
};‬

‭Lifetimes in function signatures‬
‭n‬‭
f longest‬<‬
‭'a‬
‭ >(x: &‬
‭ 'a‬‭
‭ str‬, y: &‬
‭ 'a‬‭
‭ str‬
) ->‬
‭ ‭Returning closures‬
&‬
‭'a‬‭
‭ str‬‭
{‬
if‬‭
‭ x.len() > y.len() {‬ fn‬‭
‭ add_one‬
() ->‬‭
‭ impl‬‭
Fn‬
(‭
‭ i
‬32‬
) ->‬‭
‭ i32‬‭
{‬
x‬
‭ |x| x +‬‭
‭ 1‬
}‬‭
‭ else‬‭
{‬ }‬

y‬

}‬
‭ ‭n‬‭
f add_or_subtract‬ (x:‬‭
‭ i32‬
) ->‬‭
‭ Box‬
<dyn‬

}‬
‭ Fn‬
‭ (‬
‭ i32‬
‭ ) ->‬‭
‭ i32‬> {‬

if‬‭
‭ x >‬‭10‬‭
{‬
Box‬
‭ ::new(‬
‭ move‬‭
‭ |y| y + x)‬
‭Lifetimes in struct definitions‬ }‬‭
‭ else‬‭ {‬
struct‬‭
‭ User‬
<‬
‭'a‬
‭ > {‬
‭ Box‬
‭ ::new(‬
‭ move‬‭
‭ |y| y - x)‬
full_name: &‬
‭ 'a‬‭
‭ str‬
,‬
‭ }‬

}‬
‭ }‬

‭Static lifetimes‬ ‭Closure traits‬


let‬‭
‭ s: &‬
'static‬‭
‭ str‬‭
=‬‭
"Let’s Get Rusty!"‬
;‬
‭ ‭●‬ ‭FnOnce‬‭- consumes the variables it captures‬
‭from its enclosing scope.‬
‭●‬ ‭FnMut‬‭- mutably borrows values from its‬
‭ unctions, Function Pointers &‬
F ‭enclosing scope.‬
‭Closures‬ ‭●‬ ‭Fn‬‭- immutably borrows values from its enclosing‬
‭scope.‬
‭Associated functions and methods‬
struct‬‭
‭ Point‬‭
{ x:‬‭
i32‬
, y:‬‭
‭ i32‬
, }‬
‭ ‭Store closure in struct‬
‭truct‬‭
s Cacher‬<T>‬

impl‬‭
‭ Point {‬ where‬

// Associated function‬
‭ T:‬‭
‭ Fn‬
(‭
‭u
‬32‬) ->‬‭
‭ u32‬
,‬

fn‬‭
‭ new‬
(x:‬‭
‭ i32‬
, y:‬‭
‭ i32‬
) -> Point {‬
‭ {‬

Point { x: x, y: y }‬
‭ calculation: T,‬

}‬
‭ value:‬‭
‭ Option‬
<‭
‭u
‬32‬
>,‬

}‬

‭/ Method‬
/
fn‬‭
‭ getX‬
(&‬
‭ self‬
‭ ) ->‬‭
‭ i32‬‭
{‬‭
self‬
.x }‬

}‬

‭Function that accepts closure or function pointer‬ ‭Packages, Crates, and Modules‬
fn‬‭
‭ do_twice‬
<T>(f: T, x:‬‭
‭ i32‬
) ->‬‭
‭ i32‬
‭Definitions‬
where‬‭
‭ T:‬‭
Fn‬
(‭
‭ i
‬32‬
) ->‬‭
‭ i32‬
‭●‬ ‭Packages‬‭- A Cargo feature that lets you build,‬
{‬

‭test, and share crates.‬
f(x) + f(x)‬

‭●‬ ‭Crates‬‭- A tree of modules that produces a‬
}‬

‭library or executable.‬
‭●‬ ‭Modules‬‭and‬‭use‬‭- Let you control the‬
‭Pointers‬ ‭organization, scope, and privacy of paths.‬
‭●‬ ‭Paths‬‭- A way of naming an item, such as a‬
‭References‬
‭struct, function, or module.‬
‭et‬‭
l mut‬‭
num =‬‭
5‬
;‬

let‬‭
‭ r1 = &num;‬‭
// immutable reference‬ ‭Creating a new package with a binary crate‬
let‬‭
‭ r2 = &‬
mut‬‭
‭ num;‬‭
// mutable reference‬
$ cargo new my-project‬

‭Raw pointers‬
‭Creating a new package with a library crate‬
‭et‬‭
l mut‬‭
num =‬‭
5‬
;‬

$ cargo new my-project --lib‬

// immutable raw pointer‬

let‬‭
‭ r1 = &num‬‭
as‬‭*‭
c
‬onst‬‭
i32‬;‬

// mutable raw pointer‬
‭ ‭Defining and using modules‬
let‬‭
‭ r2 = &‬
mut‬‭
‭ num‬‭as‬‭
*‭
m
‬ut‬‭
i32‬;‬
‭ fn‬‭
‭ some_function‬
() {}‬

‭Smart pointers‬ mod‬‭


‭ outer_module {‬‭// private module‬
pub‬‭
‭ mod‬‭
inner_module {‬‭// public module‬
‭Box<T>‬‭- for allocating values on the heap‬
pub‬‭
‭ fn‬‭inner_public_function‬
() {‬

let‬‭
‭ b =‬‭
Box‬
::new(‬
‭ 5‭
‭)‬;‬ super::super::some_function();‬

}‬

‭Rc<T>‬‭-‬‭multiple ownership with reference counting‬
‭n‬‭
f inner_private_function‬
() {}‬

‭et‬‭
l a = Rc::new(‬
5‬
‭ );‬

}‬

let‬‭
‭ b = Rc::clone(&a);‬
}‬

‭ ef<T>, RefMut<T>, and RefCell<T>‬‭- enforce‬


R fn‬‭
‭ main‬
() {‬

‭borrowing rules at runtime instead of compile time.‬ // absolute path‬

‭et‬‭
l num =‬‭
5‬
;‬
‭ crate::outer_module::‬

let‬‭
‭ r1 = RefCell::new(‬
5‬
‭ );‬
‭ inner_module::inner_public_function();‬

// Ref - immutable borrow‬

let‬‭
‭ r2 = r1.borrow();‬ ‭/ relative path path‬
/
// RefMut - mutable borrow‬
‭ outer_module::‬

let‬‭
‭ r3 = r1.borrow_mut();‬ inner_module::inner_public_function();‬

// RefMut - second mutable borrow‬

let‬‭
‭ r4 = r1.borrow_mut();‬ ‭/ bringing path into scope‬
/
use‬‭
‭ outer_module::inner_module;‬
inner_module::inner_public_function();‬

‭Multiple owners of mutable data‬
}‬

let‬‭
‭ x = Rc::new(RefCell::new(‬
5‭
‭)
‬);‬
‭Renaming with‬‭as‬‭keyword‬ ‭Defining modules in separate files‬
‭se‬‭
u std::fmt::‬
Result‬
‭ ;‬
‭ ‭/ src/lib.rs‬
/
use‬‭
‭ std::io::‬
Result‬‭
‭ as‬‭
IoResult;‬ mod‬‭
‭ my_module;‬

‭Re-exporting with‬‭pub use‬ pub‬‭


‭ fn‬‭
some_function‬
() {‬

my_module::my_function();‬

mod‬‭
‭ outer_module {‬ }‬

pub‬‭
‭ mod‬‭
inner_module {‬
pub‬‭
‭ fn‬‭
inner_public_function‬
() {}‬
‭ ‭/ src/my_module.rs‬
/
}‬
‭ pub‬‭
‭ fn‬‭
my_function‬
() {}‬

}‬

pub‬‭
‭ use‬‭
crate::outer_module::inner_module;‬

You might also like