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