(for Java Developers)
MiXiT 2017 - #mixit17
#mixit17 @hannelita
OSS Projects:
#mixit17 @hannelita
'Rust is a general purpose programming language, compiled, strong and static typed, sponsored by Mozilla Research. It is designed to be a "safe, concurrent, practical language", supporting functional and imperative-procedural paradigms.'
https://en.wikipedia.org/wiki/Rust_(programming_language)#cite_note-FAQ_-_The_Rust_Project-10
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
Sometimes they are so restrictive that you can't use Java.
Which language do you choose?
Source - http://www.diva-portal.org/smash/get/diva2:215157/FULLTEXT01
#mixit17 @hannelita
#mixit17 @hannelita
It may be inconvenient.
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
fn main() {
    
}source: http://rustbyexample.com/fn.html
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
   fizzbuzz_to(n
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
}
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
    }
}
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
  fizzbuzz(n
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){
}
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){
}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }Macros
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){
}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }fn is_divisible_by
fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){
}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }fn is_divisible_by(lhs: u32, 
    rhs: u32)fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){
}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }fn is_divisible_by(lhs: u32, 
    rhs: u32) -> bool {
}fn main() {
    fizzbuzz_to(100);
}
source: http://rustbyexample.com/fn.html
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}
fn fizzbuzz(n: u32){
}
if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }fn is_divisible_by(lhs: u32, 
    rhs: u32) -> bool {
    if rhs == 0 {
        return false;
    }
    lhs % rhs == 0
}Limited type inference. Explicit type declaration for function parameters and return.
(same as in Java)
fn main() {
    fizzbuzz_to(100);
}
fn is_divisible_by(lhs: u32, rhs: u32) -> bool {
    if rhs == 0 {
        return false;
    }
    lhs % rhs == 0
}
fn fizzbuzz(n: u32) -> () {
    if is_divisible_by(n, 15) {
        println!("fizzbuzz");
    } else if is_divisible_by(n, 3) {
        println!("fizz");
    } else if is_divisible_by(n, 5) {
        println!("buzz");
    } else {
        println!("{}", n);
    }
}
fn fizzbuzz_to(n: u32) {
    for i in 1..n + 1 {
        fizzbuzz(n);
    }
}source: http://rustbyexample.com/fn.html
fn main() {
    let my_binding = 1;
    
}source: http://rustbyexample.com/variable_bindings/mut.html
fn main() {
    let my_binding = 1;
    my_binding += 1;
    
}source: http://rustbyexample.com/variable_bindings/mut.html
fn main() {
    let my_binding = 1;
    my_binding += 1;
    
}source: http://rustbyexample.com/variable_bindings/mut.html
fn main() {
    let my_binding = 1;
    my_binding += 1;
    
}source: http://rustbyexample.com/variable_bindings/mut.html
Immutability by default
fn main() {
    let my_binding = 1;
    my_binding += 1;
    let mut mutable_binding = 1;
    
}source: http://rustbyexample.com/variable_bindings/mut.html
fn main() {
    let my_binding = 1;
    my_binding += 1;
    let mut mutable_binding = 1;
    mutable_binding += 1;
    
}source: http://rustbyexample.com/variable_bindings/mut.html
fn main() {
    let my_binding = 1;
    my_binding += 1;
    let mut mutable_binding = 1;
    mutable_binding += 1;
    //^now it works! 
    
}source: http://rustbyexample.com/variable_bindings/mut.html
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: 
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)     // All natural numbers squared
             
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)   // All natural numbers squared
             .take_while(|&n| n < upper) // Below upper limit
             
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)    // All natural numbers squared
             .take_while(|&n| n < upper) // Below upper limit
             .filter(|n| is_odd(*n))     // That are odd
             
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)    // All natural numbers squared
             .take_while(|&n| n < upper) // Below upper limit
             .filter(|n| is_odd(*n))     // That are odd
             .fold(0, |sum, i| sum + i); // Sum them
    println!("result: {}",
          sum_of_squared_odd_numbers);
}source: http://rustbyexample.com/fn/hof.html
fn is_odd(n: u32) -> bool {
    n % 2 == 1
}
fn main() {
    println!("Find the sum of all the
          squared odd numbers under 1000");
    let upper = 1000;
    let sum_of_squared_odd_numbers: u32 =
        (0..).map(|n| n * n)    // All natural numbers squared
             .take_while(|&n| n < upper) // Below upper limit
             .filter(|n| is_odd(*n))     // That are odd
             .fold(0, |sum, i| sum + i); // Sum them
    println!("result: {}",
          sum_of_squared_odd_numbers);
}source: http://rustbyexample.com/fn/hof.html
High Order Functions
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
fn foo() {
    let v = vec![1, 2, 3];
    
}#mixit17 @hannelita
fn foo() {
    let v = vec![1, 2, 3];
    let v2 = v;
}#mixit17 @hannelita
fn foo() {
    let v = vec![1, 2, 3];
    let v2 = v;
    
}Rust compiler says:"error: use of moved value: `v`
println!("v[0] is: {}", v[0]);"
#mixit17 @hannelita
#mixit17 @hannelita
fn main() {
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce( v1,  v2);
}#mixit17 @hannelita
fn main() {
    fn vect_reduce
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce( v1,  v2);
}#mixit17 @hannelita
fn main() {
    
    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>)    {
        
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce( v1,  v2);
}#mixit17 @hannelita
fn main() {
    
    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce( v1,  v2);
}#mixit17 @hannelita
fn main() {
    
    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce( v1,  v2);
}#mixit17 @hannelita
fn main() {
    fn sum_vec(v: Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }
    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce( v1,  v2);
}#mixit17 @hannelita
fn main() {
    fn sum_vec(v: Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }
    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce( v1,  v2);
}I need to borrow the vectors to the function!
#mixit17 @hannelita
fn main() {
    fn sum_vec(v: Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }
    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce(&v1, &v2);
}I need to borrow the vectors to the function!
#mixit17 @hannelita
fn main() {
    fn sum_vec(v: Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }
    fn vect_reduce(v1: Vec<i32>, v2: Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce(&v1, &v2);
}Also on the function
args:
#mixit17 @hannelita
fn main() {
    fn sum_vec(v: &Vec<i32>) -> i32 {
        return v.iter().fold(0, |a, &b| a + b);
    }
    fn vect_reduce(v1: &Vec<i32>, v2: &Vec<i32>) -> i32 {
        let s1 = sum_vec(v1);
        let s2 = sum_vec(v2);
        s1 + s2
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![4, 5, 6];
    let answer = vect_reduce(&v1, &v2);
}Also on the function
args:
#mixit17 @hannelita
#mixit17 @hannelita
let v1 = vec![1, 2, 3];Reader
Reader
Reader
v1, what is
your value?
v1, what is
your value?
v1, what is
your value?
let v1 = vec![1, 2, 3];Reader
Reader
Reader
v1, what is
your value?
v1, what is
your value?
v1, what is
your value?
Writer
let v1 = vec![1, 2, 3];Reader
Reader
Reader
v1, what is
your value?
v1, what is
your value?
v1, what is
your value?
Writer
Readers, GET OUT OF HERE.
let mut v1 = vec![1, 2, 3];Writer
Writers, GET OUT OF HERE.
let mut v1 = vec![1, 2, 3];Writer
Writers, GET OUT OF HERE.
If v1 is mut, the writer can change the vector value.
(More info: https://users.cs.duke.edu/~chase/cps210-archive/slides/moresync6.pdf )
Rust uses a similar model at compile time.
Rust uses a similar model at compile time.
T: Base type; owns a value
&T: Shared reader
&mut T: Exclusive writer
(Note: I am not considering another Rust feature called Copy)
Rust uses a similar model at compile time.
T: Base type; owns a value
&T: Shared reader
&mut T: Exclusive writer
(Note: I am not considering another Rust feature called Copy)
Immutable reference
Mutable reference
fn main() {
    let mut x = 5;
    
}fn main() {
    let mut x = 5;
    let y = &mut x;
}fn main() {
    let mut x = 5;
    let y = &mut x;
    *y += 1;
}Note - * means you got a reference. You need to dereference it before you can do anything with it.
fn main() {
    let mut x = 5;
    let y = &mut x;
    *y += 1;
 
}Rust compiler says: "error: cannot borrow `x` as immutable because it is also borrowed as mutable println!("{}", x);"
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
fn lifetimes() {
    let a1 = vec![1, 2, 3]; //                 +
                                               |
                                               |
                                               |
                                               |
                                               |
                                              'a1
                                               |
}  #mixit17 @hannelita
fn lifetimes() {
    let a1 = vec![1, 2, 3]; //                 +
                                               |
                                               |
                                               |
                                               |
                                               |
                                              'a1
                                               |
}  #mixit17 @hannelita
fn lifetimes() {
    let a1 = vec![1, 2, 3]; //                 +
    let a2 = vec![4, 5, 6]; //            +    |
                            //            |    |
                                          |    |
                                          |    |
                                          |    |    
                                         'a2  'a1                                          
}  #mixit17 @hannelita
fn lifetimes() {
    let a1 = vec![1, 2, 3]; //                 +
    let a2 = vec![4, 5, 6]; //            +    |
                            //            |    |
    let b1 = &a1;           //       +    |    |
    let b2 = &a2;           //  +    |    |    |
    foo(b1);                //  |    |    |    |
    foo(b2);                // 'b2  'b1  'a2  'a1
                            //  |    |    |    |
}  #mixit17 @hannelita
fn explicit_lifetime<'a>(x: &'a i32) {
}fn multiple_lifetimes<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
}#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
http://huonw.github.io/blog/2015/05/finding-closure-in-rust/
#mixit17 @hannelita
#mixit17 @hannelita
public class MyClass { 
    private in number = 42;
    private MyOtherClass c =
      new MyOtherClass();
    public int count() {
      ..
    }
}struct MyClass {
    number: i32,
    other: MyOtherClass,
}
impl MyClass {
    fn myMethodCountHere(&self) -> i32 {
        ...
    }
}Primitive types
Primitive types
#mixit17 @hannelita
public interface MyInterface {
	void someMethod();
	
	default void someDefault(String str){
		//implementation
	}
}trait Animal {
    fn noise(&self) -> &'static str;
    fn talk(&self) {
        println!("I do not talk to humans");
    }
}
struct Horse { breed: &'static str }
impl Animal for Horse {
  fn noise(&self) -> &'static str {
    "neigh!"
    // I can't mimic horse sounds
  }
  fn talk(&self) {
      println!("{}!!!!", self.noise());
  }
}
impl Horse {
  fn move(&self) {
    //impl
  }
}#mixit17 @hannelita
public class MyGeneric<T> {
  //impl
}
public class NotGeneric {
  public static <T extends Comparable<T>> T maximum(T x, T y) {
    //awesome
  }
} 
  trait Traverse<I> {
  // methods
}
struct Bag<T> {
  //struct
}
impl<T> Bag<T> {
    //impl
}#mixit17 @hannelita
fn general_method<T: MyTrait>(t: T) { ... }
fn general_method<T: MyTrait + AnotherTrait + SomeRandomTrait>(t: T)(Trait bounds: use it for the good and for the evil)
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
fn main() {
    let u: &[u8] = &[49, 50, 51];
    unsafe {
        assert!(u == std::mem::transmute::<&str, &[u8]>("123"));
    }
}#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
#mixit17 @hannelita
https://www.ralfj.de/blog/2015/10/12/formalizing-rust.html
#mixit17 @hannelita
source: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=rust&lang2=java
#mixit17 @hannelita
Free GIF!
Questions?
hannelita@gmail.com
@hannelita