SlideShare a Scribd company logo
Introduce to Rust
A Powerful System Language
Liu, An-Chi  劉劉安⿑齊

2019.4.17
1
Acknowledgment
Lots of contents in the following slides use contents from following sources.
Great thanks to the authors!
• http://pages.di.unipi.it/corradini/Didattica/AP-18/DOCS/HaozhongZhang-
IntroToRUST.pptx
• https://nikomatsakis.github.io/rust-latam-2019/
• http://www-verimag.imag.fr/~mounier/Enseignement/Software_Security/
19RustVsC.pdf
• https://fr.slideshare.net/yann_s/introduction-to-rust-a-lowlevel-language-with-
highlevel-abstractions
• https://www.slideshare.net/jaejukim9/rust-programming-language
• https://www.slideshare.net/rodolfoeduardofinochietti/introduction-to-rust-
language-programming
!2
About
• Liu, An-Chi 劉劉安⿑齊

• ID:微中⼦子、@tigercosmos

• BIME, National Taiwan University

• Rust Taiwan Community

• ONNC team @ Skymizer

• Tennis, Animations, Coding

3
What is Rust?
From the official website (http://rust-lang.org):
“Rust is a systems programming
language that runs blazingly fast,
prevents nearly all segmentation faults,
and guarantees thread safety. ”
!4
A brief history
Pre-2009
Graydone Hoare
terrible memory leakages/bugs in Firefox
2009
Mozilla
Corp.
Experimental web browser layout
engine: Servo
2013
Samsung Corp.
Joined
2015
v1.0 Stable Released!
2019
v1.34
2018 edition
!5
Grow Up Fast
!6
Rust v1.0
Who are using Rust?
• Tilde

• Mozilla (Servo, WebRender)

• Dropbox (storage system)

• Facebook (Mercurial rewrite)

• Google (Fuschia operating system)

• Amazon (Firecracker)

• Microsoft (Azure)

• PingCAP (TiKV)
!7
Take a Look
https://github.com/rust-unofficial/awesome-rust
See more on
https://github.com/topics/rust
!8
People Love Rust
Stack Overflow 2019
Rust 83.5 %
!9
People Love Rust
Stack Overflow 2018
Rust 78.9%
!10
Advocates of Rust
!11
Control & Safety
Things make Rust Rust.
12
In the real world …
•Rust is the coating closest to the bare metal.
13
As a programming language …
•Rust is a system programming language barely on
the hardware.
• No runtime requirement (eg. GC/Dynamic Type/…)
• More control (over memory allocation/destruction/…)
• Zero-cost abstractions
• Anywhere you use C, you can use Rust
fn main() {
println!(“Hello, world!”);
}
14
More than that …
C/C++
more control,
less safety
Haskell/Python
less control,
more safety
more control,
more safety
Rust
15
What is control?
16
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);
}
16
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);
}
16
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);
}
Precise memory layout
16
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);
}
Precise memory layout
16
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);
}
Precise memory layout
Lightweight reference
16
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);
}
Precise memory layout
Lightweight reference
16
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);
}
Precise memory layout
Lightweight reference
Deterministic destruction
16
Rust’s Solution: Zero-cost
Abstraction
Rust’s Solution: Zero-cost
Abstraction
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy> = Box::new(Dummy {
a: 0,
b: 0
});
res.a = 2048;
}
Rust’s Solution: Zero-cost
Abstraction
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy> = Box::new(Dummy {
a: 0,
b: 0
});
res.a = 2048;
}
Memory allocation
Rust’s Solution: Zero-cost
Abstraction
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy> = Box::new(Dummy {
a: 0,
b: 0
});
res.a = 2048;
}
Variable binding
Memory allocation
Rust’s Solution: Zero-cost
Abstraction
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy> = Box::new(Dummy {
a: 0,
b: 0
});
res.a = 2048;
}
Variable binding
Memory allocation
Rust’s Solution: Zero-cost
Abstraction
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy> = Box::new(Dummy {
a: 0,
b: 0
});
res.a = 2048;
}
Variable binding
Memory allocation
Resource owned by res is freed automatically
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
18
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
19
Ownership
20
Ownership
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy {
a: 0,
b: 0
});
}
20
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
20
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
20
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
20
Ownership
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy {
a: 0,
b: 0
});
}
res
Stack Heap
owns
20
Ownership
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy {
a: 0,
b: 0
});
}
res
Stack Heap
owns
res is out of scope and its resource is freed automatica
20
Ownership: Lifetime
21
Ownership: Lifetime
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res: Box<Dummy>;
{
res = Box::new(Dummy {a: 0, b: 0});
}
res.a = 2048;
}
21
Ownership: Lifetime
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
21
Ownership: Lifetime
•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
21
Ownership: Unique Owner
Aliasing Mutation
22
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>) {
}
Aliasing Mutation
22
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>) {
}
Aliasing Mutation
22
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
Aliasing Mutation
22
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
Aliasing Mutation
22
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
Aliasing Mutation
22
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
22
Immutable/Shared Borrowing (&)
Aliasing Mutation
23
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;
}
Aliasing Mutation
23
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
Aliasing Mutation
23
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
Aliasing Mutation
23
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
Aliasing Mutation
23
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.
Aliasing Mutation
23
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 still owned by res. No free here.
Resource is returned from arg to res
Aliasing Mutation
23
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 still owned by res. No free here.
Resource is returned from arg to res
Aliasing Mutation
23
Immutable/Shared Borrowing (&)
•Read-only sharing
struct Dummy { a: i32, b: i32 }
fn foo() {
let mut res = Box::new(Dummy{a: 0, b: 0});
{
let alias1 = &res;
let alias2 = &res;
let alias3 = alias2;
res.a = 2048;
}
res.a = 2048;
}
Rust 2015 NLL
24
Non-lexical Lifetime
struct Dummy { a: i32, b: i32 }

fn main() {
let mut res = Box::new(Dummy { a: 0, b: 0 });

let alias1 = &res;
let alias2 = &res;
let alias3 = alias2;
res.a = 2048;
}
error[E0506]: cannot assign to `res.a` because
it is borrowed
--> src/main.rs:8:5
|
5 | let alias1 = &res;
| --- borrow of `res.a`
occurs here
...
8 | res.a = 2048;
| ^^^^^^^^^^^^ assignment to borrowed
`res.a` occurs here
Rust 2015
Finished release [optimized]
target(s) in 0.49s
Running `target/release/playground`
Rust 2018
!25
Mutable Borrowing (&mut)
Aliasing Mutation
26
Mutable Borrowing (&mut)
Aliasing Mutation
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;
}
26
Mutable Borrowing (&mut)
Aliasing Mutation
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;
}
Mutably borrowed by arg from res
26
Mutable Borrowing (&mut)
Aliasing Mutation
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;
}
Returned from arg to res
26
Mutable Borrowing (&mut)
Aliasing Mutation
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;
}
26
Mutable Borrowing (&mut)
Aliasing Mutation
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;
}
Multiple mutable borrowings
are disallowed
26
Mutability
•Every resource in Rust is immutable by default.
•mut is used to declare a resource as mutable.
27
Mutability
•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
27
Mutability
•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
27
Concurrency & Data-race Freedom
28
Concurrency & Data-race Freedom
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;
}
28
Concurrency & Data-race Freedom
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;
}
Spawn a new thread
28
Concurrency & Data-race Freedom
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;
}
Error: res is being mutably borrowed
res is mutably borrowed
Spawn a new thread
28
Type Error
!29
int main() {
unsigned int a = 4294967295;
int b = -1;
if (a == b)
printf("%u == %dn",a,b);
}
C
fn main() {
let a = 4294967295u32;
let b = -1i32;
if a == b {
┆ println!("{} == {}", a, b);
}
}
Rust
tiger@tiger:~$ rustc test.rs
error[E0308]: mismatched types
--> test.rs:4:13
|
4 | if a == b {
| ^ expected u32, found i32
error: aborting due to previous error
$ ./a.out
4294967295 == -1
No NULL
!30
enum Option {
Some(T),
None,
}
The inventor of NULL Tony Hoare apologized for inventing it at a
software conference called QCon London in 2009. He called it a
billion-dollar mistake.
• No null value struct Foo {
bar: Option<i32>,
}
fn main() {
let foo1 = Foo { bar: Some(3) };
let foo2 = Foo { bar: None };
}
Unsafe
Life is hard.
31
Raw Pointers
•Raw Pointers are inevitable in the real world.

•Compiler does NOT check the memory safety of most
operations wrt. raw pointers.

•Most operations wrt. raw pointers should be encapsulated in
a unsafe {} syntactic structure.
32
Raw Pointers
let a = 3u32;
unsafe {
let b = &a as *const u32 as *mut u32;
*b = 4;
}
println!(“a = {}”, a);
I know what I’m doing
Print “a = 4”
33
But not recommended!
More: https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html
Foreign Function Interface (FFI)
•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());
}
}
34
Inline Assembly
#![feature(asm)]
fn outl(port: u16, data: u32) {
unsafe {
asm!(“outl %0, %1”
:
: “a” (data), “d” (port)
:
: “volatile”);
}
}
35
Other Goodies
Enums, Pattern Match, Generic, Traits, Tests, …
36
Enums
•First-class
• Instead of integers (C/C++)
•Structural
• Parameters
• Replacement of union in C/C++
37
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)
}
}
38
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>>
}
39
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
40
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),
}
41
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),
}
}
42
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,
}
}
43
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,
}
}
44
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,
}
}
Generic
45
Traits
•More generic
•Typeclass in Haskell
46
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>>;
}
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,
}
}
}
Type implemented this trait
Object of the type
implementing this trait
47
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);
}
48
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);
}
49
Abstraction Without Overhead
!50
Same Performance!

(Functional version even faster)
Others
•Closures
•Concurrency
•Comments as documentations
•Macro
•Async
•Crates and modules
•…
51
Modern Conveniences
It’s 21 century now.
52
Cargo: Rust’s package manager
!53
Tests
•Rust provides a builtin test system.
54
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
55
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
56
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
57
Community
Many hands make light work!
58
!59
Rust is Open
• Open-source

• Thousands of contributors

• Open-governance

• Owned by the people who build it, not any company 

• Open-minded

• Find the best answer, not win the argument
!60
Ideas from People
• adopting the borrow checker (ownership and
borrowing)
• adopting the trait system
• adopting RFCs for decision making
• removing the runtime and garbage collector
• adopting cargo
• nightly, beta, and stable, and the 6-week releases
• introducing the Poll trait
!61
Each 	introduced by	 different 	people.
Each 	seems obvious	 now.
None 	were obvious 	at the time	.
Events in April 2019
!62
WOW many!
Learning & Development
Resources
63
Official Resources
•Rust website: http://rust-lang.org/
•Playground: https://play.rust-lang.org/
•Guide: https://doc.rust-lang.org/stable/book/
•Documents: https://doc.rust-lang.org/stable/
•User forum: https://users.rust-lang.org/
•Dev forum: https://internals.rust-lang.org/
•Source code: https://github.com/rust-lang/rust
•IRC: server: irc.mozilla.org, channel: rust
•Cargo: https://crates.io/
64
3rd Party Resources
•Rust by example: http://rustbyexample.com/
•Reddit: https://reddit.com/r/rust
•Stack Overflow: https://stackoverflow.com/
questions/tagged/rust
•Rust Primer (中⽂文): https://rustcc.gitbooks.io/
rustprimer/content/
•深入淺出 Rust
•Rust 的編程之道
65
Academic Research
•https://doc.rust-lang.org/stable/book/
academic-research.html
66
News of Rust
• This Week in Rust: https://this-week-in-rust.org/

• Rust 每⽇日新聞:https://github.com/RustStudy/
rust_daily_news
!67
Projects
• rustc: Rust compiler
• https://github.com/rust-lang/rust
• Cargo: Rust’s package manager
• https://github.com/rust-lang/cargo
• Servo: Experimental web browser layout engine
• https://github.com/servo/servo
• Piston: A user friendly game engine
• https://github.com/PistonDevelopers/piston
• TiKV: Distributed transactional key-value database
• https://github.com/tikv/tikv
• Tokio: A runtime for writing asynchronous applications
• https://github.com/tokio-rs/tokio
• On Github
• https://github.com/trending?l=rust
68
Development Environment
• VSCode
• rust langular server: https://github.com/rust-lang/rls-
vscode
• ext install vscode-rust

• Emacs
• rust-mode: https://github.com/rust-lang/rust-mode
• racer: https://github.com/phildawes/racer
• flycheck-rust: https://github.com/flycheck/flycheck-rust
• Vim
• rust.vim: https://github.com/rust-lang/rust.vim
• racer: https://github.com/rust-lang/rust.vim
69
–Niko Matsakis
“Hack Without Fear!”
!70
Questions?
71

More Related Content

Introduce to Rust-A Powerful System Language

  • 1. Introduce to Rust A Powerful System Language Liu, An-Chi  劉劉安⿑齊 2019.4.17 1
  • 2. Acknowledgment Lots of contents in the following slides use contents from following sources. Great thanks to the authors! • http://pages.di.unipi.it/corradini/Didattica/AP-18/DOCS/HaozhongZhang- IntroToRUST.pptx • https://nikomatsakis.github.io/rust-latam-2019/ • http://www-verimag.imag.fr/~mounier/Enseignement/Software_Security/ 19RustVsC.pdf • https://fr.slideshare.net/yann_s/introduction-to-rust-a-lowlevel-language-with- highlevel-abstractions • https://www.slideshare.net/jaejukim9/rust-programming-language • https://www.slideshare.net/rodolfoeduardofinochietti/introduction-to-rust- language-programming !2
  • 3. About • Liu, An-Chi 劉劉安⿑齊 • ID:微中⼦子、@tigercosmos • BIME, National Taiwan University • Rust Taiwan Community • ONNC team @ Skymizer • Tennis, Animations, Coding
 3
  • 4. What is Rust? From the official website (http://rust-lang.org): “Rust is a systems programming language that runs blazingly fast, prevents nearly all segmentation faults, and guarantees thread safety. ” !4
  • 5. A brief history Pre-2009 Graydone Hoare terrible memory leakages/bugs in Firefox 2009 Mozilla Corp. Experimental web browser layout engine: Servo 2013 Samsung Corp. Joined 2015 v1.0 Stable Released! 2019 v1.34 2018 edition !5
  • 7. Who are using Rust? • Tilde • Mozilla (Servo, WebRender) • Dropbox (storage system) • Facebook (Mercurial rewrite) • Google (Fuschia operating system) • Amazon (Firecracker) • Microsoft (Azure) • PingCAP (TiKV) !7
  • 8. Take a Look https://github.com/rust-unofficial/awesome-rust See more on https://github.com/topics/rust !8
  • 9. People Love Rust Stack Overflow 2019 Rust 83.5 % !9
  • 10. People Love Rust Stack Overflow 2018 Rust 78.9% !10
  • 12. Control & Safety Things make Rust Rust. 12
  • 13. In the real world … •Rust is the coating closest to the bare metal. 13
  • 14. As a programming language … •Rust is a system programming language barely on the hardware. • No runtime requirement (eg. GC/Dynamic Type/…) • More control (over memory allocation/destruction/…) • Zero-cost abstractions • Anywhere you use C, you can use Rust fn main() { println!(“Hello, world!”); } 14
  • 15. More than that … C/C++ more control, less safety Haskell/Python less control, more safety more control, more safety Rust 15
  • 17. 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); } 16
  • 18. 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); } 16
  • 19. 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); } Precise memory layout 16
  • 20. 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); } Precise memory layout 16
  • 21. 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); } Precise memory layout Lightweight reference 16
  • 22. 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); } Precise memory layout Lightweight reference 16
  • 23. 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); } Precise memory layout Lightweight reference Deterministic destruction 16
  • 25. Rust’s Solution: Zero-cost Abstraction struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy> = Box::new(Dummy { a: 0, b: 0 }); res.a = 2048; }
  • 26. Rust’s Solution: Zero-cost Abstraction struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy> = Box::new(Dummy { a: 0, b: 0 }); res.a = 2048; } Memory allocation
  • 27. Rust’s Solution: Zero-cost Abstraction struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy> = Box::new(Dummy { a: 0, b: 0 }); res.a = 2048; } Variable binding Memory allocation
  • 28. Rust’s Solution: Zero-cost Abstraction struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy> = Box::new(Dummy { a: 0, b: 0 }); res.a = 2048; } Variable binding Memory allocation
  • 29. Rust’s Solution: Zero-cost Abstraction struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy> = Box::new(Dummy { a: 0, b: 0 }); res.a = 2048; } Variable binding Memory allocation Resource owned by res is freed automatically
  • 30. 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 18
  • 31. 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 19
  • 33. Ownership struct Dummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy { a: 0, b: 0 }); } 20
  • 34. 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 20
  • 35. 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 20
  • 36. 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 20
  • 37. Ownership struct Dummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy { a: 0, b: 0 }); } res Stack Heap owns 20
  • 38. Ownership struct Dummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy { a: 0, b: 0 }); } res Stack Heap owns res is out of scope and its resource is freed automatica 20
  • 40. Ownership: Lifetime struct Dummy { a: i32, b: i32 } fn foo() { let mut res: Box<Dummy>; { res = Box::new(Dummy {a: 0, b: 0}); } res.a = 2048; } 21
  • 41. Ownership: Lifetime 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 21
  • 42. Ownership: Lifetime •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 21
  • 44. 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>) { } Aliasing Mutation 22
  • 45. 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>) { } Aliasing Mutation 22
  • 46. 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 Aliasing Mutation 22
  • 47. 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 Aliasing Mutation 22
  • 48. 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 Aliasing Mutation 22
  • 49. 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 22
  • 51. 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; } Aliasing Mutation 23
  • 52. 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 Aliasing Mutation 23
  • 53. 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 Aliasing Mutation 23
  • 54. 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 Aliasing Mutation 23
  • 55. 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. Aliasing Mutation 23
  • 56. 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 still owned by res. No free here. Resource is returned from arg to res Aliasing Mutation 23
  • 57. 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 still owned by res. No free here. Resource is returned from arg to res Aliasing Mutation 23
  • 58. Immutable/Shared Borrowing (&) •Read-only sharing struct Dummy { a: i32, b: i32 } fn foo() { let mut res = Box::new(Dummy{a: 0, b: 0}); { let alias1 = &res; let alias2 = &res; let alias3 = alias2; res.a = 2048; } res.a = 2048; } Rust 2015 NLL 24
  • 59. Non-lexical Lifetime struct Dummy { a: i32, b: i32 } fn main() { let mut res = Box::new(Dummy { a: 0, b: 0 }); let alias1 = &res; let alias2 = &res; let alias3 = alias2; res.a = 2048; } error[E0506]: cannot assign to `res.a` because it is borrowed --> src/main.rs:8:5 | 5 | let alias1 = &res; | --- borrow of `res.a` occurs here ... 8 | res.a = 2048; | ^^^^^^^^^^^^ assignment to borrowed `res.a` occurs here Rust 2015 Finished release [optimized] target(s) in 0.49s Running `target/release/playground` Rust 2018 !25
  • 61. Mutable Borrowing (&mut) Aliasing Mutation 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; } 26
  • 62. Mutable Borrowing (&mut) Aliasing Mutation 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; } Mutably borrowed by arg from res 26
  • 63. Mutable Borrowing (&mut) Aliasing Mutation 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; } Returned from arg to res 26
  • 64. Mutable Borrowing (&mut) Aliasing Mutation 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; } 26
  • 65. Mutable Borrowing (&mut) Aliasing Mutation 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; } Multiple mutable borrowings are disallowed 26
  • 66. Mutability •Every resource in Rust is immutable by default. •mut is used to declare a resource as mutable. 27
  • 67. Mutability •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 27
  • 68. Mutability •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 27
  • 70. Concurrency & Data-race Freedom 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; } 28
  • 71. Concurrency & Data-race Freedom 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; } Spawn a new thread 28
  • 72. Concurrency & Data-race Freedom 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; } Error: res is being mutably borrowed res is mutably borrowed Spawn a new thread 28
  • 73. Type Error !29 int main() { unsigned int a = 4294967295; int b = -1; if (a == b) printf("%u == %dn",a,b); } C fn main() { let a = 4294967295u32; let b = -1i32; if a == b { ┆ println!("{} == {}", a, b); } } Rust tiger@tiger:~$ rustc test.rs error[E0308]: mismatched types --> test.rs:4:13 | 4 | if a == b { | ^ expected u32, found i32 error: aborting due to previous error $ ./a.out 4294967295 == -1
  • 74. No NULL !30 enum Option { Some(T), None, } The inventor of NULL Tony Hoare apologized for inventing it at a software conference called QCon London in 2009. He called it a billion-dollar mistake. • No null value struct Foo { bar: Option<i32>, } fn main() { let foo1 = Foo { bar: Some(3) }; let foo2 = Foo { bar: None }; }
  • 76. Raw Pointers •Raw Pointers are inevitable in the real world. •Compiler does NOT check the memory safety of most operations wrt. raw pointers. •Most operations wrt. raw pointers should be encapsulated in a unsafe {} syntactic structure. 32
  • 77. Raw Pointers let a = 3u32; unsafe { let b = &a as *const u32 as *mut u32; *b = 4; } println!(“a = {}”, a); I know what I’m doing Print “a = 4” 33 But not recommended! More: https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html
  • 78. Foreign Function Interface (FFI) •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()); } } 34
  • 79. Inline Assembly #![feature(asm)] fn outl(port: u16, data: u32) { unsafe { asm!(“outl %0, %1” : : “a” (data), “d” (port) : : “volatile”); } } 35
  • 80. Other Goodies Enums, Pattern Match, Generic, Traits, Tests, … 36
  • 81. Enums •First-class • Instead of integers (C/C++) •Structural • Parameters • Replacement of union in C/C++ 37
  • 82. 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) } } 38
  • 83. 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>> } 39
  • 84. 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 40
  • 85. 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), } 41
  • 86. 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), } } 42
  • 87. 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, } } 43
  • 88. 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, } } 44
  • 89. 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, } } Generic 45
  • 91. 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>>; } 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, } } } Type implemented this trait Object of the type implementing this trait 47
  • 92. 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); } 48
  • 93. 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); } 49
  • 94. Abstraction Without Overhead !50 Same Performance!
 (Functional version even faster)
  • 96. Modern Conveniences It’s 21 century now. 52
  • 97. Cargo: Rust’s package manager !53
  • 98. Tests •Rust provides a builtin test system. 54
  • 99. 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 55
  • 100. 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 56
  • 101. 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 57
  • 102. Community Many hands make light work! 58
  • 103. !59
  • 104. Rust is Open • Open-source • Thousands of contributors • Open-governance • Owned by the people who build it, not any company • Open-minded • Find the best answer, not win the argument !60
  • 105. Ideas from People • adopting the borrow checker (ownership and borrowing) • adopting the trait system • adopting RFCs for decision making • removing the runtime and garbage collector • adopting cargo • nightly, beta, and stable, and the 6-week releases • introducing the Poll trait !61 Each introduced by different people. Each seems obvious now. None were obvious at the time .
  • 106. Events in April 2019 !62 WOW many!
  • 108. Official Resources •Rust website: http://rust-lang.org/ •Playground: https://play.rust-lang.org/ •Guide: https://doc.rust-lang.org/stable/book/ •Documents: https://doc.rust-lang.org/stable/ •User forum: https://users.rust-lang.org/ •Dev forum: https://internals.rust-lang.org/ •Source code: https://github.com/rust-lang/rust •IRC: server: irc.mozilla.org, channel: rust •Cargo: https://crates.io/ 64
  • 109. 3rd Party Resources •Rust by example: http://rustbyexample.com/ •Reddit: https://reddit.com/r/rust •Stack Overflow: https://stackoverflow.com/ questions/tagged/rust •Rust Primer (中⽂文): https://rustcc.gitbooks.io/ rustprimer/content/ •深入淺出 Rust •Rust 的編程之道 65
  • 111. News of Rust • This Week in Rust: https://this-week-in-rust.org/ • Rust 每⽇日新聞:https://github.com/RustStudy/ rust_daily_news !67
  • 112. Projects • rustc: Rust compiler • https://github.com/rust-lang/rust • Cargo: Rust’s package manager • https://github.com/rust-lang/cargo • Servo: Experimental web browser layout engine • https://github.com/servo/servo • Piston: A user friendly game engine • https://github.com/PistonDevelopers/piston • TiKV: Distributed transactional key-value database • https://github.com/tikv/tikv • Tokio: A runtime for writing asynchronous applications • https://github.com/tokio-rs/tokio • On Github • https://github.com/trending?l=rust 68
  • 113. Development Environment • VSCode • rust langular server: https://github.com/rust-lang/rls- vscode • ext install vscode-rust
 • Emacs • rust-mode: https://github.com/rust-lang/rust-mode • racer: https://github.com/phildawes/racer • flycheck-rust: https://github.com/flycheck/flycheck-rust • Vim • rust.vim: https://github.com/rust-lang/rust.vim • racer: https://github.com/rust-lang/rust.vim 69