Rust is a systems programming language that provides memory safety without using a garbage collector. It achieves memory safety through rules of ownership, borrowing, and lifetimes that are checked at compile time. These rules prevent common memory bugs like memory leaks, dangling pointers, and use-after-free errors that are common in C and C++.
11. Rule 1
Each Value Has Only ONE Owner
Rule 2
Variable Releases OWNING VALUE when Destroying
Rule 3
Not Allow to Use INVALID Variables
not owning or borrowing any value
INVALID
14. fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
→ fn main() {
let a = vec![1; 5];
let b = a;
{
let c = b;
}
let d = vec![2; 5];
foo(d);
}
variables
values
15. fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
fn main() {
→ let a = vec![1; 5];
let b = a;
{
let c = b;
}
let d = vec![2; 5];
foo(d);
}
a
vec![1;5]
variables
values
16. fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
→ let b = a;
{
let c = b;
}
let d = vec![2; 5];
foo(d);
}
a b
vec![1;5]
variables
values
17. fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = a;
{
→ let c = b;
}
let d = vec![2; 5];
foo(d);
}
a b c
vec![1;5]
variables
values
18. fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = a;
{
let c = b;
}
→ let d = vec![2; 5];
foo(d);
}
a b c d
variables
values
vec![2;5]
19. fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = a;
{
let c = b;
}
let d = vec![2; 5];
→ foo(d);
}
a b c d
variables
values
vec![2;5]
20. → fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = a;
{
let c = b;
}
let d = vec![2; 5];
foo(d);
}
a b c d v
variables
values
vec![2;5]
21. fn foo(v: Vec<i32>) {
→ println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = a;
{
let c = b;
}
let d = vec![2; 5];
foo(d);
}
a b c d v
variables
values
vec![2;5]
22. fn foo(v: Vec<i32>) {
println!("{:?}", v);
→ }
fn main() {
let a = vec![1; 5];
let b = a;
{
let c = b;
}
let d = vec![2; 5];
foo(d);
}
a b c d
variables
values
23. fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = a;
{
let c = b;
}
let d = vec![2; 5];
foo(d);
→ }
variables
values
25. fn foo(v: Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a: Vec<i32>;
→ println!("{:?}", a);
let b = vec![1; 5];
let c = b;
→ println!("{:?}", b);
}
error[E0381]: use of possibly
uninitialized variable: `a`
--> src/main.rs:7:22
|
7 | println!("{:?}", a);
| ^ use of
| possibly uninitialized `a`
error[E0382]: use of moved value: `b`
--> src/main.rs:11:22
|
10 | let c = b;
| - value moved here
11 | println!("{:?}", b);
| ^ value used
|. here after move
|
28. fn foo(v: i32) {
println!("{:?}", v);
}
→ fn main() {
let a = 10;
let b = a;
println!("{:?}", a);
let c = 20;
foo(c);
println!("{:?}", c);
}
variables
values
29. fn foo(v: i32) {
println!("{:?}", v);
}
fn main() {
→ let a = 10;
let b = a;
println!("{:?}", a);
let c = 20;
foo(c);
println!("{:?}", c);
}
variables
values
a
10
30. fn foo(v: i32) {
println!("{:?}", v);
}
fn main() {
let a = 10;
→ let b = a;
println!("{:?}", a);
let c = 20;
foo(c);
println!("{:?}", c);
}
variables
values
a b
10 10
31. fn foo(v: i32) {
println!("{:?}", v);
}
fn main() {
let a = 10;
let b = a;
→ println!("{:?}", a);
let c = 20;
foo(c);
println!("{:?}", c);
}
variables
values
a b
10 10
32. fn foo(v: i32) {
println!("{:?}", v);
}
fn main() {
let a = 10;
let b = a;
println!("{:?}", a);
→ let c = 20;
foo(c);
println!("{:?}", c);
}
variables
values
a b c
10 10 20
33. fn foo(v: i32) {
println!("{:?}", v);
}
fn main() {
let a = 10;
let b = a;
println!("{:?}", a);
let c = 20;
→ foo(c);
println!("{:?}", c);
}
variables
values
a b c
10 10 20
34. → fn foo(v: i32) {
println!("{:?}", v);
}
fn main() {
let a = 10;
let b = a;
println!("{:?}", a);
let c = 20;
foo(c);
println!("{:?}", c);
}
variables
values
a b c v
10 10 20 20
35. fn foo(v: i32) {
→ println!("{:?}", v);
}
fn main() {
let a = 10;
let b = a;
println!("{:?}", a);
let c = 20;
foo(c);
println!("{:?}", c);
}
variables
values
a b c v
10 10 20 20
36. fn foo(v: i32) {
println!("{:?}", v);
→ }
fn main() {
let a = 10;
let b = a;
println!("{:?}", a);
let c = 20;
foo(c);
println!("{:?}", c);
}
variables
values
a b c
10 10 20
37. fn foo(v: i32) {
println!("{:?}", v);
}
fn main() {
let a = 10;
let b = a;
println!("{:?}", a);
let c = 20;
foo(c);
→ println!("{:?}", c);
}
variables
values
a b c
10 10 20
38. fn foo(v: i32) {
println!("{:?}", v);
}
fn main() {
let a = 10;
let b = a;
println!("{:?}", a);
let c = 20;
foo(c);
println!("{:?}", c);
→ }
variables
values
45. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
→ fn main() {
let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
}
variables
values
46. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
fn main() {
→ let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
}
variables
values
a
vec![1;5]
47. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
→ let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
}
variables
values
a b
vec![1;5]
48. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = &a;
→ println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
}
variables
values
a b
vec![1;5]
49. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
→ let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
}
variables
values
a b c
vec![2;5]vec![1;5]
50. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
→ foo(&c);
println!("{:?}", c);
}
variables
values
a b c
vec![2;5]vec![1;5]
51. → fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
}
variables
values
a b c v
vec![2;5]vec![1;5]
52. fn foo(v: &Vec<i32>) {
→ println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
}
variables
values
a b c v
vec![2;5]vec![1;5]
53. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
→ }
fn main() {
let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
}
variables
values
a b c
vec![2;5]vec![1;5]
54. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
→ println!("{:?}", c);
}
variables
values
a b c
vec![2;5]vec![1;5]
55. fn foo(v: &Vec<i32>) {
println!("{:?}", v);
}
fn main() {
let a = vec![1; 5];
let b = &a;
println!("{:?}", a);
let c = vec![2; 5];
foo(&c);
println!("{:?}", c);
→ }
variables
values
58. Project Initialization
$ cargo new helloworld --bin
Create a new project with Cargo:
Generated files by `cargo new`:
$ tree helloworld
helloworld
!"" Cargo.toml
#"" src
#"" main.rs
59. Build & Run
$ cargo build
Compiling helloworld v0.1.0 (file:///helloworld)
Finished dev [unoptimized + debuginfo] target(s) in 4.60 secs
Build a project with cargo:
Run the executable program:
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/helloworld`
Hello, world!
60. Cargo.toml
[package]
# project name
name = "helloworld"
# project version
version = "0.1.0"
# auto info
authors = ["kuoe0 <kuoe0.tw@gmail.com>"]
[dependencies]
rand = "0.4.2" # random number generator
61. Cargo.toml
[package]
# project name
name = "helloworld"
# project version
version = "0.1.0"
# auto info
authors = ["kuoe0 <kuoe0.tw@gmail.com>"]
[dependencies]
rand = "0.4.2" # random number generator
Package Info
Dependencies List
62. Dependencies List
[package]
# project name
name = "helloworld"
# project version
version = "0.1.0"
# auto info
authors = ["kuoe0 <kuoe0.tw@gmail.com>"]
[dependencies]
rand = "0.4.2"
libc = "0.2.40"
bitflags = "1.0.3"
serde = "1.0.44"
log = "0.4.1"
64. Unit Test
extern crate rand;
fn gen_rand_int_less_100() -> u32 {
rand::random::<u32>() % 100
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_less_100() {
assert!(gen_rand_int_less_100() < 100);
}
}
65. $ cargo test
Compiling helloworld v0.1.0 (file:///private/tmp/helloworld)
Finished dev [unoptimized + debuginfo] target(s) in 0.48 secs
Running target/debug/deps/helloworld-7a8984a66f00dd7b
running 1 test
test tests::should_less_100 ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0
filtered out
Run unit test with `cargo test`
66. Documentation
extern crate rand;
/// Return a random number in [0, 100)
///
/// # Example
///
/// ```
/// let r = gen_rand_int_less_100();
/// ```
pub fn gen_rand_int_less_100() -> u32 {
rand::random::<u32>() % 100
}
67. $ cargo doc
Documenting helloworld v0.1.0 (file:///private/tmp/helloworld)
Finished dev [unoptimized + debuginfo] target(s) in 1.14 secs
Generate the document with `cargo doc`
71. Servo Browser Engine
A browser engine written in Rust with parallel mechanism
Quantum CSS (a.k.a. Stylo)
Use the parallel style engine from Servo in Firefox