Johan Burell
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.
Shared
Mutable
Concurrent
Choose two!
Memory safety
Real time computing
Many older languages [are] better than new ones. We keep forgetting already-learned lessons.
[...]
[Rust is] Technology from the past come to save the future from itself
- Graydon Hoare, Creator of Rust at Mozilla
fn main() {
println!("Hello world!");
}(also known as the worlds worst acronym)
fn main() {
let a:u32;
println!("Value: {}", a); // a?
}error[E0381]: use of possibly uninitialized variable: `a`
--> examples/ex1a.rs:3:27
|
3 | println!("Value: {}", a);
| ^ use of possibly uninitialized `a`
fn main() {
let a:u32 = 1;
println!("Value: {}", a);
}Example #1a
Example #1b
fn main() {
let a:u32 = 1;
a = 2;
println!("Value: {}", a);
}error[E0384]: re-assignment of immutable variable `a`
--> examples/ex1c.rs:3:5
|
2 | let a:u32 = 1;
| - first assignment to `a`
3 | a = 2;
| ^^^^^ re-assignment of immutable variable
fn main() {
let mut a:u32 = 1;
a = 2;
println!("Value: {}", a);
}Example #1c
warning: value assigned to `a` is never read, #[warn(unused_assignments)] on by default
--> examples/ex1d.rs:2:9
|
2 | let mut a:u32 = 1;
| Example #1d
fn create_value_ref<'a>() -> &'a u32 {
let a:u32 = 2;
return &a; // Not allowed!
}
fn create_value_move() -> u32 {
let a:u32 = 3;
return a;
}
fn main() {
let a:&u32 = create_value_ref();
println!("Value: {}", *a);
let b:u32 = create_value_move();
println!("Value: {}", b);
}
error: `a` does not live long enough
--> examples/ex1e.rs:3:13
|
3 | return &a; // Not allowed!
| ^ does not live long enough
4 | }
| - borrowed value only lives until here
Example #1e
#![feature(box_syntax)]
fn create_value() -> Box<u32> {
let a:Box<u32> = box 2;
return a;
}
fn main() {
let a:u32 = *create_value();
println!("Value: {}", a);
}
Example #1f
Running `target/debug/examples/ex1f`
Value: 2#[derive(Debug)] struct A;
#[derive(Debug, Clone)] struct B;
#[derive(Debug, Clone, Copy)] struct C;
fn move_to<T>(v: T) {
let i_have_stolen_the_v = v;
}
fn main() {
let a = A; let b = B; let c = C; let d = 3;
move_to(a);
println!("a: {:?}", a); //<-- can't do this!
move_to(b.clone());
println!("b: {:?}", b);
move_to(c);
println!("c: {:?}", c);
move_to(d);
println!("d: {:?}", d);
}Example #2a
error[E0382]: use of moved value: `a`
--> examples/ex2a.rs:12:25
|
11 | move_to(a);
| - value moved here
12 | println!("a: {:?}", a); //<-- can't do this!
| ^ value used here after move
|
= note: move occurs because `a` has type `A`, which does not implement the `Copy` trait
#[derive(Debug)]
struct A { b: B }
#[derive(Debug, Clone)]
struct B { c: i32 }
fn you_can_borrow_this(a: &A) {
let mut x = (*a).b.clone();
x = B{ c: x.c * 2 };
println!("x: {:?}", x);
}
fn main() {
let y = A{ b: B{ c: 3 } };
you_can_borrow_this(&y);
println!("y: {:?}", y);
}
Example #2b
Running `target/debug/examples/ex2b`
x: B { c: 6 }
y: A { b: B { c: 3 } }#[derive(Debug)]
struct Point {
x:f32,
y:f32,
}
fn main() {
let p = Point {x: 3.0, y: 5.2};
println!("Value: {:?}", p);
} Example #4a
Running `target/debug/examples/ex4a`
Value: Point { x: 3, y: 5.2 }struct Point {
x:f32,
y:f32,
}
struct NotAPoint {}
#[derive(Debug)]
enum ReturnVal { Point, NotAPoint }
fn main() {
let p = ReturnVal::NotAPoint;
println!("Value: {:?}", p);
}Example #4b
Running `target/debug/examples/ex4b`
Value: NotAPoint#[derive(Debug, Clone)]
enum ReturnVal { Point{ x:f32, y:f32 }, NotAPoint }
fn get_val(input:f32) -> ReturnVal {
if input > 1.0 {
ReturnVal::Point{ x: input, y: input}
} else {
ReturnVal::NotAPoint
}
}
fn main() {
let p = get_val(1.5);
println!("Value: {:?}", p);
}Example #4c
Running `target/debug/examples/ex4c`
Value: Point { x: 1.5, y: 1.5 }use std::env;
fn main() {
let mut args = env::args();
let exe = args.next(); // Name of app
let arg1 = args.next(); // Can it be NULL?!??
println!("{:?}\n{:?}", exe, arg1);
} Example #4d
Running `target/debug/examples/ex4d`
Some("target/debug/examples/ex4d")
None
use std::fs::File;
fn get_file(filename: &str) -> Result<File, std::io::Error> {
//let f = try!(File::open(filename));
let f = File::open(filename)?;
Ok(f)
}
fn main() {
match get_file("examples/ex1a.rs") {
Ok(f) => println!("{:?}", f),
Err(e) => println!("OOPS! {}", e),
}
}Example #4e
Running `target/debug/examples/ex4e`
File { fd: 3, path: "../examples/ex1a.rs", read: true, write: false }Running `target/debug/examples/ex4e`
OOPS! No such file or directory (os error 2)fn plus_two(v:i32) -> Result<i32, String> { Ok(v + 2) }
fn one_div_by(v:i32) -> Result<i32, String> {
if v == 0 {
Err("Div by 0".to_string())
} else {
Ok(1 / v)
}
}
fn times_three(v:i32) -> Result<i32, String> { Ok(v * 3) }
fn main() {
let a = Ok(-2)
.and_then(plus_two)
.and_then(one_div_by)
.and_then(times_three);
println!("{:?}", a);
}Example #4f
Running `target/debug/examples/ex4f`
Err("Div by 0")struct Coord {
x:f32,
y:f32,
z:f32,
}
fn main() {
let c = Coord{ x: 5.0, y: 4.0, z: 3.0 };
let c2 = (42, 52);
let Coord { x, z, .. } = c;
let (x2, y2) = c2;
println!("Struct x: {}, z: {}", x, z);
println!("Tuple x2: {}, y2: {}", x2, y2);
}
Example #5a
Running `target/debug/examples/ex5a`
Struct x: 5, z: 3
Tuple x2: 42, y2: 52fn test_pattern(v: i32) -> () {
match v {
a if a > 4 => println!("5 or bigger!"),
1 ... 2 => println!("1..2"),
3 | 4 => println!("3|4"),
_ => println!("Don't know!"),
}
}
fn main() {
let _:Vec<()> = (0..)
.take(6)
.map(test_pattern)
.collect();
}
Example #5b
Running `target/debug/examples/ex5b`
Don't know!
1..2
1..2
3|4
3|4
5 or bigger!
#[derive(Debug)]
struct Point { x: f32, y: f32 }
impl Point {
fn at_x5_and_y10() -> Point {
Point{x:5.0, y:10.0}
}
}
trait Double {
fn double(&self) -> Self;
}
impl Double for Point {
fn double(&self) -> Self {
Point{ x: self.x * 2.0, y: self.y * 2.0}
}
}
fn main() {
let p = Point::at_x5_and_y10();
println!("Coordinates: {:?}, {:?}", p, p.double());
}Example #6a
Running `target/debug/examples/ex6a`
Coordinates: Point { x: 5, y: 10 }, Point { x: 10, y: 20 }use std::convert::From;
use std::ops::Add;
#[derive(Debug)]
struct Celsius(f32);
struct Farenheit(f32);
impl From<Farenheit> for Celsius {
fn from(f:Farenheit) -> Self { Celsius((f.0 - 32.0) * (5.0 / 9.0)) }
}
impl Add for Celsius {
type Output = Celsius;
fn add(self, rhs:Celsius) -> Self { Celsius(self.0 + rhs.0) }
}
fn main() {
let c = Celsius(37.0);
let f = Farenheit(95.3);
println!("Temp sum: {:?}", c + Celsius::from(f));
}Example #6b
Running `target/debug/examples/ex6b`
Temp sum: Celsius(72.16667)fn main() {
let mut after_filter = vec!();
let mut after_mul = vec!();
let result:i32 = (0..10)
.filter(|v| v % 2 == 0)
.map(|v| { after_filter.push(v); v } )
.map(|v| v * 3)
.map(|v| { after_mul.push(v); v } )
.sum();
println!("The result is: {}, filter: {:?}, mul: {:?}",
result,
after_filter,
after_mul);
}Example #7a
Running `target/debug/examples/ex7a`
The result is: 60, filter: [0, 2, 4, 6, 8], mul: [0, 6, 12, 18, 24]
use std::sync::mpsc::channel;
use std::thread;
use std::sync::{Arc, Mutex};
const NUM_VALS: u32 = 5;
fn main() {
let counter = Arc::new(Mutex::new(0));
let (tx, rx) = channel();
for i in 0..NUM_VALS {
let (counter, tx) = (counter.clone(), tx.clone());
thread::spawn(move || {
let mut counter = counter.lock().unwrap();
*counter += 1;
tx.send(i).unwrap();
});
}
for _ in 0..NUM_VALS {
print!("{} ", rx.recv().unwrap());
}
print!("-> num values: {}", *counter.lock().unwrap());
}Example #8a
Running `target\debug\examples\ex8a.exe`
1 2 0 3 4 -> num values: 5//[...]
fn read_line() -> Poll<String, std::io::Error> {
sleep!(900);
to_async!("Value: 42".into())
}
fn parse_line(val: String) -> Poll<i32, std::io::Error> {
sleep!(400);
to_async!(read!("Value: {}", val.bytes()))
}
fn main() {
let start_time = time::Instant::now();
let mut future = poll_fn(read_line).map(|v| parse_line(v));
print_time_taken!(start_time.elapsed());
println!("Val: {:?}", future.poll());
print_time_taken!(start_time.elapsed());
}Example #8b
Running `target\debug\examples\ex8b.exe`
Time taken: 0.0 sec
Val: Ok(Ready(Ok(Ready(42))))
Time taken: 1.302 secSlides: https://slides.com/burre83/rust_intro
Code: https://github.com/jburell/rust_presentation
into_rust(): http://intorust.com/
AreWeWebYet?: http://arewewebyet.org/
AreWeIDEYet?: https://areweideyet.com/
TWIR: https://this-week-in-rust.org/
RustByExample: http://rustbyexample.com/
AwesomeRust: https://github.com/kud1ing/awesome-rust