Steve Klabnik
Rust is a systems programming language focusing on three things:
Rust was written by Graydon Hoare. Mozilla has taken stewardship.
Mozilla writes lots of C++, and feels that pain.
A language that doesn’t affect the way you think about programming, is not worth knowing.
Alan Perlis
In a word: Ownership
Rust is poised to be many people’s first systems language. Newbies welcome!
The compiler is here to help you, and so are we.
Rust is currently at version 1.0
New versions every six weeks!
Backwards compatible
int main(void)
{
char *s = "hello world";
*s = 'H';
}
fn main() { let s = &"hello world"; *s = "H"; }
segfault.rs:3:4: 3:6 error: type &str cannot be dereferenced
segfault.rs:3 *s = "H";
^~
error: aborting due to previous error
task 'rustc' failed at 'explicit failure', ...
fn main() { println!("Hello, world"); }
use std::thread; fn main() { let nums = [1, 2]; let odds = nums.iter().map(|&x| x * 2 - 1); }
fn plus_one(x: &i32) -> i32 { *x + 1 } fn main() { println!("{}", plus_one(&5)); }
fn plus_one(x: &i32) -> i32 { *x + 1 } fn main() { let x = Box::new(5); println!("{}", plus_one(x)); }
use std::thread; fn main() { let nums = [1, 2]; let noms = ["Tim", "Eston", "Aaron", "Ben"]; let odds = nums.iter().map(|&x| x * 2 - 1); for num in odds { thread::spawn(move || { println!("{} says hello from a thread!", noms[num]); }); } thread::sleep_ms(100); }
use std::sync::mpsc; use std::thread; fn main() { let (tx, rx) = mpsc::channel(); thread::spawn(move || { let result = 5; tx.send(result); }); let result = rx.recv().unwrap(); println!("{}", result); }
use std::sync::mpsc; use std::thread; fn main() { let (tx, rx) = mpsc::channel(); let x = Box::new(5); thread::spawn(move || { let result = 5 + *x; tx.send(result); }); let result = rx.recv().unwrap(); println!("{}", result); }
use std::sync::mpsc; use std::thread; fn main() { let (tx, rx) = mpsc::channel(); let x = Box::new(5); thread::spawn(move || { let result = 5 + *x; tx.send(result); }); *x += 5; let result = rx.recv().unwrap(); println!("{}", result); }
13:12 error: use of moved value: `*x` [E0382]
*x += 5;
^~~~~~~
11:6 note: `x` moved into closure environment here because it has type `[closure(())]`, which is non-copyable
thread::spawn(move || {
let result = 5 + *x;
tx.send(result);
});
note: in expansion of closure expansion
11:6 note: expansion site
11:6 help: perhaps you meant to use `clone()`?
13:12 error: cannot assign to immutable `Box` content `*x`
*x += 5;
^~~~~~~
match my_number { 0 => println("zero"), 1 | 2 => println("one or two"), 3..10 => println("three to ten"), _ => println("something else") }
let msg = Some("howdy"); // Take a reference to the contained string match msg { Some(ref m) => println!("{}", m), None => () }
let nums = [1, 2, 3]; let square = |x| x * x; let max: Vec<i32> = nums.iter().map(square).collect();
fn foo<A, B>(x: A, y: B) { // ... }
struct TimeBomb { explosivity: uint } impl Drop for TimeBomb { fn drop(&mut self) { for _ in range(0, self.explosivity) { println("blam!"); } } }
trait Seq<T> { fn length(&self) -> u32; } impl<T> Seq<T> for Vec<T> { fn length(&self) -> u32 { self.len() } }
extern mod active_support; use active_support::Period; use active_support::Time; fn main() { let time = Time::now(); println!("{:?}", time); println!("{:?}", 2.days().from_now()); println!("{:?}", 2.weeks().from_now()); println!("{:?}", 2.months().from_now()); println!("{:?}", 2.years().from_now()); }
use TimeChange; pub trait Period { fn seconds(&self) -> TimeChange; fn minutes(&self) -> TimeChange; // ... } impl Period for uint { fn seconds(&self) -> TimeChange { TimeChange::new().seconds(*self as f32) } fn minutes(&self) -> TimeChange { TimeChange::new().minutes(*self as f32) } // ... }
use std::libc::size_t; #[link(name = "snappy")] extern { fn snappy_max_compressed_length(source_length: size_t) -> size_t; } fn main() { let x = unsafe { snappy_max_compressed_length(100) }; println!("max compressed length of a 100 byte buffer: {}", x); }
pub fn validate_compressed_buffer(src: &[u8]) -> bool { unsafe { snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0 } }
pub fn uncompress(src: &[u8]) -> Option<Vec<u8>> { unsafe { let srclen = src.len() as size_t; let psrc = src.as_ptr(); let mut dstlen: size_t = 0; snappy_uncompressed_length(psrc, srclen, &mut dstlen); let mut dst = vec::with_capacity(dstlen as uint); let pdst = dst.as_mut_ptr(); if snappy_uncompress(psrc, srclen, pdst, &mut dstlen) == 0 { dst.set_len(dstlen as uint); Some(dst) } else { None // SNAPPY_INVALID_INPUT } } }
Write a Ruby gem in Rust!
Write a Node module in Rust!
Write a Python extension in Rust!
$ cargo new foo --bin
$ cd foo
$ cargo run
Compiling foo v0.1.0 (file:///home/steve/tmp/foo)
Running `target/debug/foo`
Hello, world!
[package]
name = “foo”
version = “0.1.0”
authors = [“Steve Klabnik <steve@steveklabnik.com>”]
[package]
name = "foo"
version = "0.1.0"
authors = ["Steve Klabnik <steve@steveklabnik.com>"]
[dependencies]
regex = "0.1.33"
$ cargo build
Updating registry `https://github.com/rust-lang/crates.io-index`
Downloading regex v0.1.33
Downloading regex-syntax v0.1.2
Compiling regex-syntax v0.1.2
Compiling regex v0.1.33
Compiling foo v0.1.0 (file:///home/steve/tmp/foo)
Yes thanks everyone, Rust has been a much more significant move than we had thought. We have performance, increased safety, modularity, traits etc. In addition we have found something even more significant, first time working code. By this I mean debugging time is almost zero (beyond logic errors of course) in comparison, for example our last IP library (rUDP in c++) was a 5 month job to remove data races (luckily we used all clang sanitisers and static analysis in build and CI, but never the less).
Same task in Rust, worked of the bat, same with next layer (routing) and then next layer (vaults). This is very significant indeed and I am happy to discuss this further. I think it is vastly underestimated.
I have also found an interesting paradigm here, Ruby, Python, Jave, c# etc. programmers just lift Rust and code almost immediately (seeking out libraries and asking questions). C/C++ (especially library level) actually take a huge time to transition, it is like they have to “unlearn fear”. I say this as somebody who did a lot of c++ (dirvine on github). Not true of all, of course, but also a surprise.
https://github.com/rust-lang/rust
<3
Steve Klabnik