KEMBAR78
Introduction to Rust language programming | PPTX
Introduction to Rust language
programming
Rodolfo Finochietti
Chief Delivery Officer
@rodolfof
rodolfof@lagash.com
DISCLAIMER
This session is best suited for programming languages nerds
Most loved languages
https://insights.stackoverflow.com/survey/2018
What is Rust?
https://www.rust-lang.org
Rust is a systems programming language
focused on three goals: safety, speed, and
concurrency.
More than that …
C/C++
more control,
less safety
Haskell/Python/C#/Java
less control,
more safety
more control,
more safety
Rust
Why Rust
• Open Source and Open Governance
• Top-tier performance
• Like C/C++ or better​​​​
• Memory safe
• No memory leak
• No runtime, no GC
• Runs everywhere
• No undefined behavior
• Zero-cost abstractions
• Ergonomic syntax
• Expressive data structures
• Targets the same use cases as C/C++  
• All of them
• Sponsored by Mozilla
• Makers of Firefox
Embrace the challengelagash.com
Abrief history
Pre-2009
Graydone Hoare
terrible memory leakages/bugs in Firefox
2009
Mozilla
Corp.
2013
Samsung Corp.
Joined
2015/05/15
v1.0 Stable Released!
Embrace the challengelagash.com
Soft
• Web browser
• Firefox
• Servo: Mozilla's parallel web browser engine developed in collaboration with Samsung
• Quantum:a project, composed of several sub-projects, to improve the Gecko web browser engine of Firefox, developed by
Mozilla
• Operating system
• Magic Pocket: Dropbox's file system that powers their Diskotech petabyte storage machines
• Redox: a microkernel operating system
• Stratis: a file system planned for Fedora 28
• Railcae: a container runtime by Oracle
• Firecracker: secure and fast microVMs for serverless computing[58]
• Other
• exa: a "modern replacement for ls“
• Microsoft Azure IoT Edge: a platform used to run Azure services and artificial intelligence on IoT devices has components
implemented in Rust
• OpenDNS:used in two of its components[60][61][62]
• Tor: an anonymity network, written in C originally, is experimenting with porting to Rust for its security features.
• Wargroove: a video game developed by Chucklefish that uses Rust for its server software
• Xi: a text editor from Raph Levien,[66] used within the Fuchsia operating system.[67]
Control & Safety
Things make Rust Rust
Embrace the challengelagash.com
What is control?
typedef struct Dummy { int a; int b; } Dummy;
void foo(void) {
Dummy *ptr = (Dummy *) malloc(sizeof(struct Dummy));
ptr->a = 2048;
free(ptr);
}
ptr
.a
.b
Stack
Heap
Precise memory layout
Lightweight reference
Deterministic destruction
.a = 2048
Embrace the challengelagash.com
Rust’s Solution: Zero-costAbstraction
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy> = Box::new(Dummy {
a: 0,
b: 0
});
res.a = 2048;
}
res
.a = 0
.b = 0
Stack
Heap
.a = 2048
Variable binding
Memory allocation
Resource owned by res is freed automatically
Embrace the challengelagash.com
Type Inference
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy> = Box::new(Dummy {
a: 0,
b: 0
});
res.a = 2048;
}
Embrace the challengelagash.com
What is safety?
typedef struct Dummy { int a; int b; } Dummy;
void foo(void) {
Dummy *ptr = (Dummy *) malloc(sizeof(struct Dummy));
Dummy *alias = ptr;
free(ptr);
int a = alias.a;
free(alias);
}
ptr
alias
.a
.b
Stack
Heap
Dangling Pointer
Use after free
Double free
Aliasing Mutation
Embrace the challengelagash.com
Rust’s Solution: Ownership & Borrowing
Compiler enforces:
Every resource has a unique owner.
Others can borrow the resource from its owner.
Owner cannot free or mutate its resource while it is borrowed.
Aliasing Mutation
No need for runtime Memory safety Data-race freedom
Embrace the challengelagash.com
Ownership
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy {
a: 0,
b: 0
});
}
res
.a = 0
.b = 0
Stack
Heap
owns
res is out of scope and its resource is freed automatically
Embrace the challengelagash.com
Lifetime is determined and checked statically.
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy>;
{
res = Box::new(Dummy {a: 0, b: 0});
}
res.a = 2048;
}
Lifetime that res
owns the resource.
Compiling Error: res no longer owns the resource
Ownership: Lifetime
Embrace the challengelagash.com
Ownership: Unique Owner
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy {
a: 0,
b: 0
});
take(res);
println!(“res.a = {}”, res.a);
}
fn take(arg: Box<Dummy>) {
}
Ownership is moved from res to arg
arg is out of scope and the resource is freed automatically
Compiling Error!
Aliasing Mutation
Embrace the challengelagash.com
Immutable/Shared Borrowing (&)
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy{
a: 0,
b: 0
});
take(&res);
res.a = 2048;
}
fn take(arg: &Box<Dummy>) {
arg.a = 2048;
}
Resource is immutably borrowed by arg from res
Resource is still owned by res. No free here.
Resource is returned from arg to res
Aliasing Mutation
Compiling Error: Cannot mutate via
an immutable reference
Embrace the challengelagash.com
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy{a: 0, b: 0});
take(&mut res);
res.a = 4096;
let borrower = &mut res;
let alias = &mut res;
}
fn take(arg: &mut Box<Dummy>) {
arg.a = 2048;
}
Mutable Borrowing (&mut)
Aliasing Mutation
Mutably borrowed by arg from res
Returned from arg to res
Multiple mutable borrowings
are disallowed
Embrace the challengelagash.com
Every resource in Rust is immutable by default.
mut is used to declare a resource as mutable.
struct Dummy { a: i32, b: i32 }
fn foo() {
let res = Box::new(Dummy{a: 0, b: 0});
res.a = 2048;
let borrower = &mut res;
}
Error: Resource is immutable
Error: Cannot get a mutable borrowing
of an immutable resource
Mutability
Embrace the challengelagash.com
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy {a: 0, b: 0});
std::thread::spawn(move || {
let borrower = &mut res;
borrower.a += 1;
});
res.a += 1;
}
Concurrency & Data-race Freedom
Error: res is being mutably borrowed
res is mutably borrowed
Spawn a new thread
Embrace the challengelagash.com
Unsafe
Life is hard
Embrace the challengelagash.com
Mutably sharing is inevitable in the real world.
Example: mutable doubly linked list
prev
next
prev
next
prev
next
struct Node {
prev: option<Box<Node>>,
next: option<Box<Node>>
}
Mutably Sharing
Embrace the challengelagash.com
Compiler does NOT check the memory safety of most operations wrt. raw pointers.
Most operations wrt. raw pointers should be encapsulatedin a unsafe {} syntactic structure.
prev
next
prev
next
prev
next
struct Node {
prev: option<Box<Node>>,
next: *mut Node
}
Raw pointer
Rust’s Solution: Raw Pointers
Embrace the challengelagash.com
let a = 3;
unsafe {
let b = &a as *const u32 as *mut u32;
*b = 4;
}
println!(“a = {}”, a);
Rust’s Solution: Raw Pointers
I know what I’m doing
Print “a = 4”
Embrace the challengelagash.com
All foreign functions are unsafe.
extern {
fn write(fd: i32, data: *const u8, len: u32) -> i32;
}
fn main() {
let msg = b”Hello, world!n”;
unsafe {
write(1, &msg[0], msg.len());
}
}
Foreign Function Interface (FFI)
Embrace the challengelagash.com
InlineAssembly
#![feature(asm)]
fn outl(port: u16, data: u32) {
unsafe {
asm!(“outl %0, %1”
:
: “a” (data), “d” (port)
:
: “volatile”);
}
}
Embrace the challengelagash.com
Other Goodies
Enums, Pattern Match, Generic, Traits,
Tests, …
Embrace the challengelagash.com
Generic
struct SLStack {
top: Option<Box<Slot>>
}
struct Slot {
data: Box<u32>,
prev: Option<Box<Slot>>
}
fn is_empty(stk: &SLStack) -> bool {
match stk.top {
None => true,
Some(..) => false,
}
}
struct SLStack<T> {
top: Option<Box<Slot<T>>>
}
struct Slot<T> {
data: Box<T>,
prev: Option<Box<Slot<T>>>
}
fn is_empty<T>(stk: &SLStack<T>) -> bool {
match stk.top {
None => true,
Some(..) => false,
}
}
Embrace the challengelagash.com
Enums
First-class
 Instead of integers (C/C++)
Structural
 Parameters
 Replacement of union in C/C++
Embrace the challengelagash.com
Enums
enum RetInt {
Fail(u32),
Succ(u32)
}
fn foo_may_fail(arg: u32) -> RetInt {
let fail = false;
let errno: u32;
let result: u32;
...
if fail {
RetInt::Fail(errno)
} else {
RetInt::Succ(result)
}
}
Embrace the challengelagash.com
Enums: No Null Pointers
enum std::option::Option<T> {
None,
Some(T)
}
struct SLStack {
top: Option<Box<Slot>>
}
struct Slot {
data: Box<u32>,
prev: Option<Box<Slot>>
}
Embrace the challengelagash.com
Pattern Match
let x = 5;
match x {
1 => println!(“one”),
2 => println!(“two”),
3|4 => println!(“three or four”),
5 ... 10 => println!(“five to ten”),
e @ 11 ... 20 => println!(“{}”, e);
_ => println!(“others”),
}
Compiler enforces the matching is complete
Embrace the challengelagash.com
Pattern Match
let x = Dummy{ a: 2048, b: 4096 };
match x {
Dummy{ a: va, b: vb } => va + vb,
}
match x {
Dummy{ a: va, .. } => println!(“a={}”, va),
}
Embrace the challengelagash.com
Pattern Match
enum RetInt {
Fail(u32),
Succ(u32)
}
fn foo_may_fail(arg: u32) -> RetInt {
...
}
fn main() {
match foo_may_fail(2048) {
Fail(errno) => println!(“Failed w/ err={}”,
errno),
Succ(result) => println!(“Result={}”, result),
}
}
Embrace the challengelagash.com
Pattern Match
enum std::option::Option<T> {
None,
Some(T)
}
struct SLStack {
top: Option<Box<Slot>>
}
fn is_empty(stk: &SLStack) -> bool {
match stk.top {
None => true,
Some(..) => false,
}
}
Embrace the challengelagash.com
Traits
• More generic
• Typeclass in Haskell
Embrace the challengelagash.com
trait Stack<T> {
fn new() -> Self;
fn is_empty(&self) -> bool;
fn push(&mut self, data: Box<T>);
fn pop(&mut self) -> Option<Box<T>>;
}
impl<T> Stack<T> for SLStack<T> {
fn new() -> SLStack<T> {
SLStack{ top: None }
}
fn is_empty(&self) -> bool {
match self.top {
None => true,
Some(..) => false,
}
}
}
Traits Type implemented this trait
Object of the type
implementing this trait
Embrace the challengelagash.com
Traits
trait Stack<T> {
fn new() -> Self;
fn is_empty(&self) -> bool;
fn push(&mut self, data: Box<T>);
fn pop(&mut self) -> Option<Box<T>>;
}
fn generic_push<T, S: Stack<T>>(stk: &mut S,
data: Box<T>) {
stk.push(data);
}
fn main() {
let mut stk = SLStack::<u32>::new();
let data = Box::new(2048);
generic_push(&mut stk, data);
}
Embrace the challengelagash.com
Traits
trait Clone {
fn clone(&self) -> Self;
}
impl<T> Clone for SLStack<T> {
...
}
fn immut_push<T, S: Stack<T>+Clone>(stk: &S, data: Box<T>) -> S {
let mut dup = stk.clone();
dup.push(data);
dup
}
fn main() {
let stk = SLStack::<u32>::new();
let data = Box::new(2048);
let stk = immut_push(&stk, data);
}
Embrace the challengelagash.com
Test
Rust provides a builtin test system.
Embrace the challengelagash.com
Tests
#[test]
fn test_pop_empty_stack() {
let stk = SLStack::<u32>::new();
assert!(stk.pop() == None);
}
Testing annotation
$ rustc --test slstack.rs; ./slstack
running 1 test
test test_pop_empty_stack … ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
Passed
Embrace the challengelagash.com
Tests
#[test]
fn test_pop_empty_stack() {
let stk = SLStack::<u32>::new();
assert!(stk.pop() == None);
}
Testing annotation
$ rustc --test slstack.rs; ./slstack
running 1 test
test test_pop_empty_stack … FAILED
--- test_pop_empty_stack stdout ---
thread ‘test_pop_empty_stack’ panicked at ‘assertion failed: stk.pop() ==
None’, slstack.rs: 4
failures:
test_pop_empty_stack
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
Failed
Embrace the challengelagash.com
Documentation Tests
/// # Examples
/// ```
/// let stk = SLStack::<u32>::new();
/// assert!(stk.pop() == None);
/// ```
fn pop(&mut self) -> Option<Box<T>> {
...
}
$ rustdoc --test slstack.rs; ./slstack
running 1 test
test test_pop_empty_stack_0 … ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
Passed
Embrace the challengelagash.com
Instalation
• Arch Linux: pacman -S rustup
• Unix: curl https://sh.rustup.rs -sSf | sh
• Windows: download and run the rustup-init.exe
Embrace the challengelagash.com
Build
lagash.com
Questions?
Argentina | Buenos Aires
+54 (11) 4982 4185
info@lagash.com
Chile | Santiago de Chile
+56 (2) 2231 9428
info_chile@lagash.com
Colombia | Bogotá
+57 (1) 750 5276
info_colombia@lagash.com
México | México DF
+52 (55) 6394 0617
info_mexico@lagash.com
USA | Seattle - US
+1 844 4 Lagash
infousa@lagash.com
Uruguay | Montevideo
+598 2623 2546
info_uy@lagash.com
Let’s keep in touch

Introduction to Rust language programming

  • 1.
    Introduction to Rustlanguage programming Rodolfo Finochietti Chief Delivery Officer @rodolfof rodolfof@lagash.com
  • 2.
    DISCLAIMER This session isbest suited for programming languages nerds
  • 3.
  • 4.
    What is Rust? https://www.rust-lang.org Rustis a systems programming language focused on three goals: safety, speed, and concurrency.
  • 5.
    More than that… C/C++ more control, less safety Haskell/Python/C#/Java less control, more safety more control, more safety Rust
  • 6.
    Why Rust • OpenSource and Open Governance • Top-tier performance • Like C/C++ or better​​​​ • Memory safe • No memory leak • No runtime, no GC • Runs everywhere • No undefined behavior • Zero-cost abstractions • Ergonomic syntax • Expressive data structures • Targets the same use cases as C/C++   • All of them • Sponsored by Mozilla • Makers of Firefox
  • 7.
    Embrace the challengelagash.com Abriefhistory Pre-2009 Graydone Hoare terrible memory leakages/bugs in Firefox 2009 Mozilla Corp. 2013 Samsung Corp. Joined 2015/05/15 v1.0 Stable Released!
  • 8.
    Embrace the challengelagash.com Soft •Web browser • Firefox • Servo: Mozilla's parallel web browser engine developed in collaboration with Samsung • Quantum:a project, composed of several sub-projects, to improve the Gecko web browser engine of Firefox, developed by Mozilla • Operating system • Magic Pocket: Dropbox's file system that powers their Diskotech petabyte storage machines • Redox: a microkernel operating system • Stratis: a file system planned for Fedora 28 • Railcae: a container runtime by Oracle • Firecracker: secure and fast microVMs for serverless computing[58] • Other • exa: a "modern replacement for ls“ • Microsoft Azure IoT Edge: a platform used to run Azure services and artificial intelligence on IoT devices has components implemented in Rust • OpenDNS:used in two of its components[60][61][62] • Tor: an anonymity network, written in C originally, is experimenting with porting to Rust for its security features. • Wargroove: a video game developed by Chucklefish that uses Rust for its server software • Xi: a text editor from Raph Levien,[66] used within the Fuchsia operating system.[67]
  • 9.
  • 10.
    Embrace the challengelagash.com Whatis control? typedef struct Dummy { int a; int b; } Dummy; void foo(void) { Dummy *ptr = (Dummy *) malloc(sizeof(struct Dummy)); ptr->a = 2048; free(ptr); } ptr .a .b Stack Heap Precise memory layout Lightweight reference Deterministic destruction .a = 2048
  • 11.
    Embrace the challengelagash.com Rust’sSolution: Zero-costAbstraction struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy> = Box::new(Dummy { a: 0, b: 0 }); res.a = 2048; } res .a = 0 .b = 0 Stack Heap .a = 2048 Variable binding Memory allocation Resource owned by res is freed automatically
  • 12.
    Embrace the challengelagash.com TypeInference struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy> = Box::new(Dummy { a: 0, b: 0 }); res.a = 2048; }
  • 13.
    Embrace the challengelagash.com Whatis safety? typedef struct Dummy { int a; int b; } Dummy; void foo(void) { Dummy *ptr = (Dummy *) malloc(sizeof(struct Dummy)); Dummy *alias = ptr; free(ptr); int a = alias.a; free(alias); } ptr alias .a .b Stack Heap Dangling Pointer Use after free Double free Aliasing Mutation
  • 14.
    Embrace the challengelagash.com Rust’sSolution: Ownership & Borrowing Compiler enforces: Every resource has a unique owner. Others can borrow the resource from its owner. Owner cannot free or mutate its resource while it is borrowed. Aliasing Mutation No need for runtime Memory safety Data-race freedom
  • 15.
    Embrace the challengelagash.com Ownership structDummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy { a: 0, b: 0 }); } res .a = 0 .b = 0 Stack Heap owns res is out of scope and its resource is freed automatically
  • 16.
    Embrace the challengelagash.com Lifetimeis determined and checked statically. struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy>; { res = Box::new(Dummy {a: 0, b: 0}); } res.a = 2048; } Lifetime that res owns the resource. Compiling Error: res no longer owns the resource Ownership: Lifetime
  • 17.
    Embrace the challengelagash.com Ownership:Unique Owner struct Dummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy { a: 0, b: 0 }); take(res); println!(“res.a = {}”, res.a); } fn take(arg: Box<Dummy>) { } Ownership is moved from res to arg arg is out of scope and the resource is freed automatically Compiling Error! Aliasing Mutation
  • 18.
    Embrace the challengelagash.com Immutable/SharedBorrowing (&) struct Dummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy{ a: 0, b: 0 }); take(&res); res.a = 2048; } fn take(arg: &Box<Dummy>) { arg.a = 2048; } Resource is immutably borrowed by arg from res Resource is still owned by res. No free here. Resource is returned from arg to res Aliasing Mutation Compiling Error: Cannot mutate via an immutable reference
  • 19.
    Embrace the challengelagash.com structDummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy{a: 0, b: 0}); take(&mut res); res.a = 4096; let borrower = &mut res; let alias = &mut res; } fn take(arg: &mut Box<Dummy>) { arg.a = 2048; } Mutable Borrowing (&mut) Aliasing Mutation Mutably borrowed by arg from res Returned from arg to res Multiple mutable borrowings are disallowed
  • 20.
    Embrace the challengelagash.com Everyresource in Rust is immutable by default. mut is used to declare a resource as mutable. struct Dummy { a: i32, b: i32 } fn foo() { let res = Box::new(Dummy{a: 0, b: 0}); res.a = 2048; let borrower = &mut res; } Error: Resource is immutable Error: Cannot get a mutable borrowing of an immutable resource Mutability
  • 21.
    Embrace the challengelagash.com structDummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy {a: 0, b: 0}); std::thread::spawn(move || { let borrower = &mut res; borrower.a += 1; }); res.a += 1; } Concurrency & Data-race Freedom Error: res is being mutably borrowed res is mutably borrowed Spawn a new thread
  • 22.
  • 23.
    Embrace the challengelagash.com Mutablysharing is inevitable in the real world. Example: mutable doubly linked list prev next prev next prev next struct Node { prev: option<Box<Node>>, next: option<Box<Node>> } Mutably Sharing
  • 24.
    Embrace the challengelagash.com Compilerdoes NOT check the memory safety of most operations wrt. raw pointers. Most operations wrt. raw pointers should be encapsulatedin a unsafe {} syntactic structure. prev next prev next prev next struct Node { prev: option<Box<Node>>, next: *mut Node } Raw pointer Rust’s Solution: Raw Pointers
  • 25.
    Embrace the challengelagash.com leta = 3; unsafe { let b = &a as *const u32 as *mut u32; *b = 4; } println!(“a = {}”, a); Rust’s Solution: Raw Pointers I know what I’m doing Print “a = 4”
  • 26.
    Embrace the challengelagash.com Allforeign functions are unsafe. extern { fn write(fd: i32, data: *const u8, len: u32) -> i32; } fn main() { let msg = b”Hello, world!n”; unsafe { write(1, &msg[0], msg.len()); } } Foreign Function Interface (FFI)
  • 27.
    Embrace the challengelagash.com InlineAssembly #![feature(asm)] fnoutl(port: u16, data: u32) { unsafe { asm!(“outl %0, %1” : : “a” (data), “d” (port) : : “volatile”); } }
  • 28.
    Embrace the challengelagash.com OtherGoodies Enums, Pattern Match, Generic, Traits, Tests, …
  • 29.
    Embrace the challengelagash.com Generic structSLStack { top: Option<Box<Slot>> } struct Slot { data: Box<u32>, prev: Option<Box<Slot>> } fn is_empty(stk: &SLStack) -> bool { match stk.top { None => true, Some(..) => false, } } struct SLStack<T> { top: Option<Box<Slot<T>>> } struct Slot<T> { data: Box<T>, prev: Option<Box<Slot<T>>> } fn is_empty<T>(stk: &SLStack<T>) -> bool { match stk.top { None => true, Some(..) => false, } }
  • 30.
    Embrace the challengelagash.com Enums First-class Instead of integers (C/C++) Structural  Parameters  Replacement of union in C/C++
  • 31.
    Embrace the challengelagash.com Enums enumRetInt { Fail(u32), Succ(u32) } fn foo_may_fail(arg: u32) -> RetInt { let fail = false; let errno: u32; let result: u32; ... if fail { RetInt::Fail(errno) } else { RetInt::Succ(result) } }
  • 32.
    Embrace the challengelagash.com Enums:No Null Pointers enum std::option::Option<T> { None, Some(T) } struct SLStack { top: Option<Box<Slot>> } struct Slot { data: Box<u32>, prev: Option<Box<Slot>> }
  • 33.
    Embrace the challengelagash.com PatternMatch let x = 5; match x { 1 => println!(“one”), 2 => println!(“two”), 3|4 => println!(“three or four”), 5 ... 10 => println!(“five to ten”), e @ 11 ... 20 => println!(“{}”, e); _ => println!(“others”), } Compiler enforces the matching is complete
  • 34.
    Embrace the challengelagash.com PatternMatch let x = Dummy{ a: 2048, b: 4096 }; match x { Dummy{ a: va, b: vb } => va + vb, } match x { Dummy{ a: va, .. } => println!(“a={}”, va), }
  • 35.
    Embrace the challengelagash.com PatternMatch enum RetInt { Fail(u32), Succ(u32) } fn foo_may_fail(arg: u32) -> RetInt { ... } fn main() { match foo_may_fail(2048) { Fail(errno) => println!(“Failed w/ err={}”, errno), Succ(result) => println!(“Result={}”, result), } }
  • 36.
    Embrace the challengelagash.com PatternMatch enum std::option::Option<T> { None, Some(T) } struct SLStack { top: Option<Box<Slot>> } fn is_empty(stk: &SLStack) -> bool { match stk.top { None => true, Some(..) => false, } }
  • 37.
    Embrace the challengelagash.com Traits •More generic • Typeclass in Haskell
  • 38.
    Embrace the challengelagash.com traitStack<T> { fn new() -> Self; fn is_empty(&self) -> bool; fn push(&mut self, data: Box<T>); fn pop(&mut self) -> Option<Box<T>>; } impl<T> Stack<T> for SLStack<T> { fn new() -> SLStack<T> { SLStack{ top: None } } fn is_empty(&self) -> bool { match self.top { None => true, Some(..) => false, } } } Traits Type implemented this trait Object of the type implementing this trait
  • 39.
    Embrace the challengelagash.com Traits traitStack<T> { fn new() -> Self; fn is_empty(&self) -> bool; fn push(&mut self, data: Box<T>); fn pop(&mut self) -> Option<Box<T>>; } fn generic_push<T, S: Stack<T>>(stk: &mut S, data: Box<T>) { stk.push(data); } fn main() { let mut stk = SLStack::<u32>::new(); let data = Box::new(2048); generic_push(&mut stk, data); }
  • 40.
    Embrace the challengelagash.com Traits traitClone { fn clone(&self) -> Self; } impl<T> Clone for SLStack<T> { ... } fn immut_push<T, S: Stack<T>+Clone>(stk: &S, data: Box<T>) -> S { let mut dup = stk.clone(); dup.push(data); dup } fn main() { let stk = SLStack::<u32>::new(); let data = Box::new(2048); let stk = immut_push(&stk, data); }
  • 41.
    Embrace the challengelagash.com Test Rustprovides a builtin test system.
  • 42.
    Embrace the challengelagash.com Tests #[test] fntest_pop_empty_stack() { let stk = SLStack::<u32>::new(); assert!(stk.pop() == None); } Testing annotation $ rustc --test slstack.rs; ./slstack running 1 test test test_pop_empty_stack … ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Passed
  • 43.
    Embrace the challengelagash.com Tests #[test] fntest_pop_empty_stack() { let stk = SLStack::<u32>::new(); assert!(stk.pop() == None); } Testing annotation $ rustc --test slstack.rs; ./slstack running 1 test test test_pop_empty_stack … FAILED --- test_pop_empty_stack stdout --- thread ‘test_pop_empty_stack’ panicked at ‘assertion failed: stk.pop() == None’, slstack.rs: 4 failures: test_pop_empty_stack test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured Failed
  • 44.
    Embrace the challengelagash.com DocumentationTests /// # Examples /// ``` /// let stk = SLStack::<u32>::new(); /// assert!(stk.pop() == None); /// ``` fn pop(&mut self) -> Option<Box<T>> { ... } $ rustdoc --test slstack.rs; ./slstack running 1 test test test_pop_empty_stack_0 … ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured Passed
  • 45.
    Embrace the challengelagash.com Instalation •Arch Linux: pacman -S rustup • Unix: curl https://sh.rustup.rs -sSf | sh • Windows: download and run the rustup-init.exe
  • 46.
  • 47.
  • 48.
    Argentina | BuenosAires +54 (11) 4982 4185 info@lagash.com Chile | Santiago de Chile +56 (2) 2231 9428 info_chile@lagash.com Colombia | Bogotá +57 (1) 750 5276 info_colombia@lagash.com México | México DF +52 (55) 6394 0617 info_mexico@lagash.com USA | Seattle - US +1 844 4 Lagash infousa@lagash.com Uruguay | Montevideo +598 2623 2546 info_uy@lagash.com Let’s keep in touch

Editor's Notes

  • #12 This is actually generally used with C++. It means paying no penalty for the abstraction, or said otherwise, it means that whether you use the abstraction or instead go for the "manual" implementation you end up having the same costs (same speed, same memory consumption, ...).
  • #14 https://en.wikipedia.org/wiki/Dangling_pointer
  • #38 https://doc.rust-lang.org/1.15.1/book/match.html
  • #39 https://doc.rust-lang.org/rust-by-example/trait.html
  • #42 https://doc.rust-lang.org/rust-by-example/trait.html