Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intro to Rust Programming Language

Intro to Rust Programming Language

Rust is a systems programming language focused on three goals: safety, speed, and concurrency. In this talk, you will get a high-level overview of the language, its syntax and semantics, and some code examples.

Rida Al Barazi

February 25, 2016

Transcript

88 slides
  1. Rust is a systems programming language focused on three goals:

    safety, speed, and concurrency Source: rust-lang.org What is rust
  2. Why and when? • Embedding in other languages • Writing

    low-level code • Small programs with specific space and time requirements
  3. Installation 1.6.0 is the latest major release Came out on

    January 21, 2016 Install your system package from: https://www.rust-lang.org/downloads.html
  4. dependencies versions [dependencies] rand="0.3.0" # This a shorthand for ^0.3.0

    rand=“^0.3.0" # Use any release compatible with this specific version. Semantic Versioning rand=“=0.3.0" # Use only 0.3.0 exactly rand=“*" # Use latest version
  5. dependencies versions ! cargo build Downloading libc v0.2.7 Downloading rand

    v0.3.14 Compiling libc v0.2.7 Compiling rand v0.3.14 Compiling hello_world v0.1.0 (file:/// home/yourname/projects/hello_world)
  6. variable binding let x = 5; // Type inferred as

    i32 let x: i32 = 5; // Explicitly bind with the type i32
  7. variable binding let x = 5; // Type inferred as

    i32 let x: i32 = 5; // Explicitly bound with the type i32 let (x, y) = (1, 2); // Pattern matching
  8. variable binding let x = 5; // Type inferred as

    i32 let x: i32 = 5; // Explicitly bound with the type i32 let (x, y) = (1, 2); // Pattern matching y = 3; // Raises an error. Immutable by default let mut y = 3; // y is now mutable and is bound to 3
  9. scoping and shadowing let x: i32 = 8; { println!("{}",

    x); // Prints "8" let x = 12; println!("{}", x); // Prints "12" } println!("{}", x); // Prints "8" let x = 42; println!("{}", x); // Prints "42"
  10. numeric types let x = 42; // x has type

    i32 let y = 1.0; // y has type f64
  11. arrays let a = [1, 2, 3]; // a: [i32;

    3] let mut m = [1, 2, 3]; // m: [i32; 3]
  12. arrays let a = [1, 2, 3]; // a: [i32;

    3] let mut m = [1, 2, 3]; // m: [i32; 3] // Arrays have type [T; N] let a = [0; 20]; // a: [i32; 20]
  13. arrays let a = [1, 2, 3]; // a: [i32;

    3] let mut m = [1, 2, 3]; // m: [i32; 3] // Arrays have type [T; N] let a = [0; 20]; // a: [i32; 20] // Get the length println!("a has {} elements", a.len()); //> a has 20 elements
  14. arrays let a = [1, 2, 3]; // a: [i32;

    3] let mut m = [1, 2, 3]; // m: [i32; 3] // Arrays have type [T; N] let a = [0; 20]; // a: [i32; 20] // The `len` method yields the size of the array println!("a has {} elements", a.len()); //> a has 20 elements let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3] println!("The second name is: {}", names[1]); //> The second name is: Brian
  15. tuples let tuple = (1, "hello", "world"); // x: (i32,

    &str, &str) // Indexing let v = tuple.1; println!("v is {}", v); // v is hello
  16. tuples let tuple = (1, "hello", "world"); // x: (i32,

    &str, &str) // Indexing let v = tuple.1; println!("v is {}", v); // v is hello // Deconstructing let (x, y, z) = (1, 2, 3); println!("x is {}", x); // x is 1
  17. structs struct Point { x: i32, y: i32, } fn

    main() { let mut point = Point { x: 0, y: 0 }; point.x = 5; println!("The point is at ({}, {})", point.x, point.y); let point = point; // this new binding can’t change now point.y = 6; // this causes an error }
  18. structs // Tuple Struct struct Inches(i32); let length = Inches(10);

    let Inches(integer_length) = length; println!("length is {} inches", integer_length); //> length is 10 inches // Unit-like Struct struct Electron; let x = Electron; // Empty tuple: ()
  19. enums enum Message { // An `enum` may either be

    `unit-like`, Quit, // like tuple structs, ChangeColor(i32, i32, i32), // or like structures. Move { x: i32, y: i32 }, Write(String), } let m: Message = Message::Write("Hello, world".to_string());
  20. operators // Integer addition println!("1 + 2 = {}", 1

    + 2); // Integer subtraction println!("1 - 2 = {}", 1 - 2);
  21. operators // Integer addition println!("1 + 2 = {}", 1

    + 2); // Integer subtraction println!("1 - 2 = {}", 1 - 2); // Short-circuiting boolean logic println!("true AND false is {}", true && false); println!("true OR false is {}", true || false); println!("NOT true is {}", !true);
  22. operators // Integer addition println!("1 + 2 = {}", 1

    + 2); // Integer subtraction println!("1 - 2 = {}", 1 - 2); // Short-circuiting boolean logic println!("true AND false is {}", true && false); println!("true OR false is {}", true || false); println!("NOT true is {}", !true); // Use underscores to improve readability! println!("One million is written as {}", 1_000_000);
  23. GENERIC FUNCTIONS fn takes_anything<T>(x: T) { // do something with

    x } fn takes_two_things<T, U>(x: T, y: U) { // ... }
  24. GENERIC STRUCTS struct Point<T> { x: T, y: T, }

    let int_origin = Point { x: 0, y: 0 }; let float_origin = Point { x: 0.0, y: 0.0 };
  25. vectors // The `vec!` macro can be used to initialize

    a vector let mut v = vec![1, 2, 3, 4, 5]; // v: Vec<i32>
  26. vectors // The `vec!` macro can be used to initialize

    a vector let mut v = vec![1, 2, 3, 4, 5]; // v: Vec<i32> v.push(4); // Insert new element at the end of the vector
  27. vectors // The `vec!` macro can be used to initialize

    a vector let mut v = vec![1, 2, 3, 4, 5]; // v: Vec<i32> v.push(4); // Insert new element at the end of the vector // The `len` method yields the current size of the vector println!("Vector size: {}", v.len()); //> Vector size: 6 println!("Sixth element: {}", v[5]); //> Sixth element: 4
  28. strings // &str let greeting = "Hello there."; // greeting:

    &'static str = &str // String let mut s = "Hello".to_string(); // mut s: String println!("{}", s); //> "Hello" s.push_str(", world."); println!("{}", s); //> "Hello, World"
  29. strings • They are a sequence of UTF-8 bytes. •

    &str is a string slice. • String is a growable string. • "Hello there" is statically allocated string literal, typed string slice. • str.to_string() creates a new String, which is expensive. • string.as_slice() returns a view of the string, which is cheap.
  30. if let x = 5; if x == 5 {

    println!("x is five!"); } else if x == 6 { println!("x is six!"); } else { println!("x is not five or six :("); }
  31. if let x = 5; if x == 5 {

    println!("x is five!"); } else if x == 6 { println!("x is six!"); } else { println!("x is not five or six :("); } let y = if x == 5 { 10 } else { 15 }; // y: i32
  32. loops loop { println!("Loop forever!"); } let mut x =

    5; loop { x += x - 3; println!("{}", x); if x % 5 == 0 { break; } }
  33. loops let mut x = 5; // mut x: i32

    let mut done = false; // mut done: bool while !done { x += x - 3; println!("{}", x); if x % 5 == 0 { done = true; } }
  34. loops for x in 0..10 { println!("{}", x); // x:

    i32 } for (idx,j) in (5..10).enumerate() { println!("idx = {} and j = {}", i, j); } // idx = 0 and j = 5 // idx = 1 and j = 6 // idx = 2 and j = 7 // idx = 3 and j = 8 // idx = 4 and j = 9
  35. loops 'outer: for x in 0..10 { 'inner: for y

    in 0..10 { if x % 2 == 0 { continue 'outer; } // continues the loop over x if y % 2 == 0 { continue 'inner; } // continues the loop over y println!("x: {}, y: {}", x, y); } }
  36. match let x = 5; match x { 1 =>

    println!("one"), 2 => println!("two"), 3 => println!("three"), 4 => println!("four"), 5 => println!("five"), _ => println!("something else"), }
  37. match enum Message { Quit, ChangeColor(i32, i32, i32), Move {

    x: i32, y: i32 }, Write(String), } fn quit() { /* ... */ } fn change_color(r: i32, g: i32, b: i32) { /* ... */ } fn move_cursor(x: i32, y: i32) { /* ... */ } fn process_message(msg: Message) { match msg { Message::Quit => quit(), Message::ChangeColor(r, g, b) => change_color(r, g, b), Message::Move { x: x, y: y } => move_cursor(x, y), Message::Write(s) => println!("{}", s), }; }
  38. functions fn main() { let x = 5; print_sum(add_one(x), 6);

    // sum is: 12 } fn print_sum(x: i32, y: i32) { println!("sum is: {}", x + y); } fn add_one(x: i32) -> i32 { x + 1 // note that there's no semicolon = `return` }
  39. methods To call a method on an struct instance like:

    `circle.area()`, you have to use `impl` and declare functions that accept a variant of `self`, `&self`, or `&mut self` as their first parameter.
  40. methods struct Circle { x: f64, y: f64, radius: f64,

    } impl Circle { fn area(&self) -> f64 { std::f64::consts::PI * (self.radius * self.radius) } } fn main() { let c = Circle { x: 0.0, y: 0.0, radius: 2.0 }; println!("{}", c.area()); }
  41. methods struct Circle { x: f64, y: f64, radius: f64,

    } impl Circle { // new is an associated function fn new(x: f64, y: f64, radius: f64) -> Circle { Circle { x: x, y: y, radius: radius, } } } fn main() { let c = Circle::new(0.0, 0.0, 2.0);
  42. Methods Rust doesn’t have method overloading, named arguments, or variable

    arguments. Instead you would use the Builder Pattern
  43. Methods struct Circle { x: f64, y: f64, radius: f64,

    } impl Circle { fn area(&self) -> f64 { std::f64::consts::PI * (self.radius * self.radius) } } struct CircleBuilder { x: f64, y: f64, radius: f64, }
  44. Methods impl CircleBuilder { fn new() -> CircleBuilder { CircleBuilder

    { x: 0.0, y: 0.0, radius: 1.0, } } fn x(&mut self, coordinate: f64) -> &mut CircleBuilder { self.x = coordinate; self } fn y(&mut self, coordinate: f64) -> &mut CircleBuilder { self.y = coordinate; self } fn radius(&mut self, radius: f64) -> &mut CircleBuilder { self.radius = radius; self } fn finalize(&self) -> Circle { Circle { x: self.x, y: self.y, radius: self.radius } } }
  45. Methods fn main() { let c = CircleBuilder::new() .x(1.0) .y(2.0)

    .radius(2.0) .finalize(); println!("area: {}", c.area()); println!("x: {}", c.x); println!("y: {}", c.y); }
  46. traits Similar to methods you can add functionality to structs

    by specifying what Traits a struct implements.
  47. traits struct Circle { x: f64, y: f64, radius: f64,

    } trait HasArea { fn area(&self) -> f64; } impl HasArea for Circle { fn area(&self) -> f64 { std::f64::consts::PI * (self.radius * self.radius) } }
  48. ownership let v = vec![1, 2, 3]; let v2 =

    v; println!("v[0] is: {}", v[0]); // error: use of moved value: `v`
  49. ownership let v = 1; let v2 = v; println!("v

    is: {}", v); // v is i32 which is a primitive. // All primitive types implement the `Copy` trait
  50. references and borrowing let v = vec![1, 2, 3]; let

    v2 = &v; println!("v[0] is: {}", v[0]); // v[0] is: 1 println!("v2[1] is: {}", v2[1]); // v2[1] is: 2
  51. references and borrowing let mut x = 5; { let

    y = &mut x; *y += 1; } println!("{}", x);
  52. Syntax and style • Indentation is 4 spaces (no tabs)

    • variable names are underscore lowercased • structs begin with a capital letter and are camel cased
  53. resources • The Rust Programming Language (online book) • https://doc.rust-lang.org/stable/book/

    • Rust by Example • http://rustbyexample.com/index.html • Rust Cheat Sheet • http://clchiou.github.io/2015-01-09/rust- cheat-sheet/ • ConFreaks Rust Talks • http://confreaks.tv/tags/155

More Decks by Rida Al Barazi

Other Decks in Programming