SlideShare a Scribd company logo
The Amazing
Borrow Checker!
By Mario A. Santini
Mario A. Santini
a Software Developer
in Telco.
Rust Ownership Rules
●
Each value in Rust has a variable that’s called its owner
●
There can only be one owner at a time
●
When the owner goes out of scope, the value will be
dropped
RAII
Resource Acquisition Is Initialization
Some Examples
...
let my_var = 1;
let another_var = my_var;
println!(“My var {}”, my_var); // ← can’t be done!
...
let my_var = String::from(“Hello SoCraTeN!”);
require_ownership(my_var); // ← move ownership
println!(“My var {}”, my_var); // ← can’t be done!
...
fn require_ownership(s: String) { // ← this signature requires ownership
// some cool stuff here...
}
Borrowing
...
let my_var = 1;
let another_var = &my_var; // ← this is borrowed!
println!(“My var {}”, my_var); // ← now it’s perfectly fine
...
let my_var = String::from(“Hello SoCraTeN!”);
doesnt_require_borrow(&my_var); // ← move don’t happen
println!(“My var {}”, my_var); // ← now it’s fine
...
fn doesnt_require_borrow(s: &String) { // ← this signature requires borrowed
// some cool stuff here...
}
Slices
Let s = String:from(“Hello World”);
Let s1: &str = &s[6..11];
println!(“:= {}”, s1); // → := World
Slices
name value
ptr
len 11
capacity 11
index value
0 H
1 e
2 l
3 l
4 0
5
6 W
7 o
8 r
9 l
10 d
s: String
name value
ptr
len 5
s1: &str
Heap
Stack
The Wrong Way
Fighting the borrow checker
The Good Way
Borrow Checker is a friend!
Just try to follow the rules
Lifetime
fn main() {
let r; // ---------+-- 'a
// |
{ // |
let x = 5; // -+-- 'b |
r = &x; // | |
} // -+ |
// |
println!("r: {}", r); // |
} // ---------+
Compiling playground v0.0.1 (/playground)
error[E0597]: `x` does not live long enough
--> src/main.rs:6:13
|
6 | r = &x; // | |
| ^^ borrowed value does not live long enough
7 | } // -+ |
| - `x` dropped here while still borrowed
8 | // |
9 | println!("r: {}", r); // |
| - borrow later used here
For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` due to previous error
Lifetime Annotation Why
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() {
x
} else {
y
}
}
Lifetime Annotation
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
Lifetime Use Example
fn main() {
let string1 = String::from("long string is long");
{
let string2 = String::from("xyz");
let result = longest(string1.as_str(), string2.as_str());
println!("The longest string is {}", result);
}
}
fn main() {
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
}
println!("The longest string is {}", result);
}
Copy vs Clone
Copy
Usually cheap
Copy just the reference
Clone
Usually heavy
Copy the memory and create
a new reference.
The Reference Counting
●
Allow more than one owner
●
It enforce the safety at runtime
3
4
5 10 Nil
b
c
a
The Reference Counting
use std::rc::Rc;
enum List {
Cons(i32, Rc<List>),
Nil,
}
fn main() {
let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
let b = Cons(3, Rc::clone(&a)); // clone the Rc!
let c = Cons(4, Rc::clone(&a)); // clone the Rc!
}
// This code does not work as Cons → List::Cons and Nil → List:Nil
NO Thread Safe!
use std::cell::Cell;
pub struct Cell<T>
where
T: ?Sized, { /* private fields */ }
pub fn set(&self, val: T)
pub fn get(&self) -> T
pub fn get_mut(&mut self) -> &mut T
...
NO Thread Safe!
use std::cell::RefCell;
pub struct RefCell<T> where
    T: ?Sized,  { /* private fields */ }
pub fn borrow(&self) -> Ref<'_, T>
pub fn borrow_mut(&self) -> RefMut<'_, T>
...
NO Thread Safe!
Interior Mutability Cell<T>/RefCell<T>
use std::cell::{RefCell, RefMut};
use std::collections::HashMap;
use std::rc::Rc;
fn main() {
let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new()));
// Create a new block to limit the scope of the dynamic borrow
{
let mut map: RefMut<_> = shared_map.borrow_mut();
map.insert("africa", 92388);
map.insert("kyoto", 11837);
map.insert("piccadilly", 11826);
map.insert("marbles", 38);
}
// Note that if we had not let the previous borrow of the cache fall out
// of scope then the subsequent borrow would cause a dynamic thread panic.
// This is the major hazard of using `RefCell`.
let total: i32 = shared_map.borrow().values().sum();
println!("{total}");
}
References
●
Rust book: The Rust Programming Language
– (https://doc.rust-lang.org/book/)
●
Rustonomincon
– (https://doc.rust-lang.org/nomicon/)
●
Jon Gjengset YouTube channel
– (https://www.youtube.com/c/JonGjengset)
●
Rust Playground
– (https://play.rust-lang.org/)
Thank You!
Have any question?
Please go ahead! :)

More Related Content

Similar to The_Borrow_Checker.pdf

Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Yandex
 
Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrup
SyedHaroonShah4
 

Similar to The_Borrow_Checker.pdf (20)

proxyc CSAPP Web proxy NAME IMPORTANT Giv.pdf
  proxyc  CSAPP Web proxy   NAME    IMPORTANT Giv.pdf  proxyc  CSAPP Web proxy   NAME    IMPORTANT Giv.pdf
proxyc CSAPP Web proxy NAME IMPORTANT Giv.pdf
 
C++11 move semantics
C++11 move semanticsC++11 move semantics
C++11 move semantics
 
Idiomatic Javascript (ES5 to ES2015+)
Idiomatic Javascript (ES5 to ES2015+)Idiomatic Javascript (ES5 to ES2015+)
Idiomatic Javascript (ES5 to ES2015+)
 
C++ Core Guidelines
C++ Core GuidelinesC++ Core Guidelines
C++ Core Guidelines
 
Game Design and Development Workshop Day 1
Game Design and Development Workshop Day 1Game Design and Development Workshop Day 1
Game Design and Development Workshop Day 1
 
Introduction to Rust language programming
Introduction to Rust language programmingIntroduction to Rust language programming
Introduction to Rust language programming
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developers
 
Functions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrupFunctions And Header Files In C++ | Bjarne stroustrup
Functions And Header Files In C++ | Bjarne stroustrup
 
C++ boot camp part 1/2
C++ boot camp part 1/2C++ boot camp part 1/2
C++ boot camp part 1/2
 
C++ Boot Camp Part 1
C++ Boot Camp Part 1C++ Boot Camp Part 1
C++ Boot Camp Part 1
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
 
Best practices for crafting high quality PHP apps (php[world] 2019)
Best practices for crafting high quality PHP apps (php[world] 2019)Best practices for crafting high quality PHP apps (php[world] 2019)
Best practices for crafting high quality PHP apps (php[world] 2019)
 
Bologna Developer Zone - About Kotlin
Bologna Developer Zone - About KotlinBologna Developer Zone - About Kotlin
Bologna Developer Zone - About Kotlin
 
JavaScript in 2015
JavaScript in 2015JavaScript in 2015
JavaScript in 2015
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Day 1
Day 1Day 1
Day 1
 

More from Mario Alexandro Santini

More from Mario Alexandro Santini (9)

A Safe Dock for our Programs
A Safe Dock for our ProgramsA Safe Dock for our Programs
A Safe Dock for our Programs
 
Rust With async / .await
Rust With async / .awaitRust With async / .await
Rust With async / .await
 
Rust_Threads.pdf
Rust_Threads.pdfRust_Threads.pdf
Rust_Threads.pdf
 
Vuejs
VuejsVuejs
Vuejs
 
The Rust Programming Language
The Rust Programming LanguageThe Rust Programming Language
The Rust Programming Language
 
Introduction to typescript
Introduction to typescriptIntroduction to typescript
Introduction to typescript
 
The myth of the small script
The myth of the small scriptThe myth of the small script
The myth of the small script
 
Docker jug taa
Docker   jug taaDocker   jug taa
Docker jug taa
 
Lambda architecture
Lambda architectureLambda architecture
Lambda architecture
 

Recently uploaded

Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
Alluxio, Inc.
 

Recently uploaded (20)

Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM Integration
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
AI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning Framework
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by Skilrock
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Studiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting softwareStudiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting software
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
 

The_Borrow_Checker.pdf

  • 2. Mario A. Santini a Software Developer in Telco.
  • 3. Rust Ownership Rules ● Each value in Rust has a variable that’s called its owner ● There can only be one owner at a time ● When the owner goes out of scope, the value will be dropped
  • 5. Some Examples ... let my_var = 1; let another_var = my_var; println!(“My var {}”, my_var); // ← can’t be done! ... let my_var = String::from(“Hello SoCraTeN!”); require_ownership(my_var); // ← move ownership println!(“My var {}”, my_var); // ← can’t be done! ... fn require_ownership(s: String) { // ← this signature requires ownership // some cool stuff here... }
  • 6. Borrowing ... let my_var = 1; let another_var = &my_var; // ← this is borrowed! println!(“My var {}”, my_var); // ← now it’s perfectly fine ... let my_var = String::from(“Hello SoCraTeN!”); doesnt_require_borrow(&my_var); // ← move don’t happen println!(“My var {}”, my_var); // ← now it’s fine ... fn doesnt_require_borrow(s: &String) { // ← this signature requires borrowed // some cool stuff here... }
  • 7. Slices Let s = String:from(“Hello World”); Let s1: &str = &s[6..11]; println!(“:= {}”, s1); // → := World
  • 8. Slices name value ptr len 11 capacity 11 index value 0 H 1 e 2 l 3 l 4 0 5 6 W 7 o 8 r 9 l 10 d s: String name value ptr len 5 s1: &str Heap Stack
  • 9. The Wrong Way Fighting the borrow checker
  • 10. The Good Way Borrow Checker is a friend! Just try to follow the rules
  • 11. Lifetime fn main() { let r; // ---------+-- 'a // | { // | let x = 5; // -+-- 'b | r = &x; // | | } // -+ | // | println!("r: {}", r); // | } // ---------+
  • 12. Compiling playground v0.0.1 (/playground) error[E0597]: `x` does not live long enough --> src/main.rs:6:13 | 6 | r = &x; // | | | ^^ borrowed value does not live long enough 7 | } // -+ | | - `x` dropped here while still borrowed 8 | // | 9 | println!("r: {}", r); // | | - borrow later used here For more information about this error, try `rustc --explain E0597`. error: could not compile `playground` due to previous error
  • 13. Lifetime Annotation Why fn longest(x: &str, y: &str) -> &str { if x.len() > y.len() { x } else { y } }
  • 14. Lifetime Annotation fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } }
  • 15. Lifetime Use Example fn main() { let string1 = String::from("long string is long"); { let string2 = String::from("xyz"); let result = longest(string1.as_str(), string2.as_str()); println!("The longest string is {}", result); } } fn main() { let string1 = String::from("long string is long"); let result; { let string2 = String::from("xyz"); result = longest(string1.as_str(), string2.as_str()); } println!("The longest string is {}", result); }
  • 16. Copy vs Clone Copy Usually cheap Copy just the reference Clone Usually heavy Copy the memory and create a new reference.
  • 17. The Reference Counting ● Allow more than one owner ● It enforce the safety at runtime 3 4 5 10 Nil b c a
  • 18. The Reference Counting use std::rc::Rc; enum List { Cons(i32, Rc<List>), Nil, } fn main() { let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); let b = Cons(3, Rc::clone(&a)); // clone the Rc! let c = Cons(4, Rc::clone(&a)); // clone the Rc! } // This code does not work as Cons → List::Cons and Nil → List:Nil NO Thread Safe!
  • 19. use std::cell::Cell; pub struct Cell<T> where T: ?Sized, { /* private fields */ } pub fn set(&self, val: T) pub fn get(&self) -> T pub fn get_mut(&mut self) -> &mut T ... NO Thread Safe!
  • 20. use std::cell::RefCell; pub struct RefCell<T> where     T: ?Sized,  { /* private fields */ } pub fn borrow(&self) -> Ref<'_, T> pub fn borrow_mut(&self) -> RefMut<'_, T> ... NO Thread Safe!
  • 21. Interior Mutability Cell<T>/RefCell<T> use std::cell::{RefCell, RefMut}; use std::collections::HashMap; use std::rc::Rc; fn main() { let shared_map: Rc<RefCell<_>> = Rc::new(RefCell::new(HashMap::new())); // Create a new block to limit the scope of the dynamic borrow { let mut map: RefMut<_> = shared_map.borrow_mut(); map.insert("africa", 92388); map.insert("kyoto", 11837); map.insert("piccadilly", 11826); map.insert("marbles", 38); } // Note that if we had not let the previous borrow of the cache fall out // of scope then the subsequent borrow would cause a dynamic thread panic. // This is the major hazard of using `RefCell`. let total: i32 = shared_map.borrow().values().sum(); println!("{total}"); }
  • 22. References ● Rust book: The Rust Programming Language – (https://doc.rust-lang.org/book/) ● Rustonomincon – (https://doc.rust-lang.org/nomicon/) ● Jon Gjengset YouTube channel – (https://www.youtube.com/c/JonGjengset) ● Rust Playground – (https://play.rust-lang.org/)
  • 23. Thank You! Have any question? Please go ahead! :)