“Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.”
gdb
, Visual Studiorustup toolchain install stable-msvc
rustup toolchain install stable-apple-darwin
rustup component add rust-src rust-analysis rls
$ cargo new --bin hello
Created binary (application) `hello` project
$ cd hello
$ cargo run
Compiling hello v0.1.0 (file:///home/grayshade/hello)
Finished dev [unoptimized + debuginfo] target(s) in 0.34 secs
Running `target/debug/hello`
Hello, world!
$ tree
.
├── Cargo.toml
└── src
└── main.rs
[package]
name = "hello"
version = "0.1.0"
authors = ["Laurentiu Nicola <lnicola@dend.ro>"]
[dependencies]
fn main() {
println!("Hello, world!");
}
cargo build
cargo run
cargo clean
cargo install rustfmt
cargo fmt
[dependencies]
cairo-rs = "0.2"
glib = "0.3"
num = "0.1"
rayon = "0.8.2"
extern crate cairo;
extern crate glib;
extern crate num;
extern crate rayon;
fn main() {
let name = "Matilda";
let age = 2;
println!("Miau! Sunt {} și am {} ani.", name, age);
}
println!
verificat la compilare!
let mut balance = 100;
balance += 10;
println!("The account balance is {}", balance);
Variabilele (bindings!) sunt în general imutabile
ArrayList<Integer> xoxo = new ArrayList<>();
xoxo.add(42);
xoxo.remove("why‽");
i8
,
u8
,
i16
,
u16
,
i32
,
u32
,
usize
f32
,
f64
bool
char
String
,
&str
enum
,
struct
&c.
let age: u8 = 2;
fn double(n: i32) -> i32 {
n * 2
}
fn main() {
println!("The answer is {}", double(21));
}
let mut odds = 0;
let mut evens = 0;
for i in 0..100 {
if i % 2 == 0 {
evens += 1;
} else {
odds += 1;
}
}
let mut numbers = [10, 19, 30];
numbers[2] = 20;
let mut colours = vec!["red", "green", "blue"];
colours.push("fuchsia");
println!("Some colours I know are: {:?}", colours);
println!("But today I prefer: {:?}", &colours[0..2]);
(0..100)
.map(|i| i * 3)
.filter(|i| i % 2 == 1)
.sum();
IEnumerable
(C#),
Stream
(Java)
enum Movement {
Walk(f32),
Turn(f32),
Jump
}
let movement = get_command();
match movement {
Movement::Walk(distance) => walk(distance),
Movement::Turn(angle) => turn(angle),
Movement::Jump => jump(),
}
match
este verificat de compilator
let s = match x {
0 => "zero",
1 => "one",
2 => "a couple",
3 | 4 => "three",
5..10 => "many",
_ => "a lot",
};
#[derive(Debug)]
struct Point {
x: f32,
y: f32,
}
impl Point {
fn new(x: f32, y: f32) -> Self {
Point { x: x, y: y }
}
}
let p = Point::new(2.0, 8.0);
println!("{:?}", p);
enum Option<T> {
None,
Some(T),
}
let mut x = None;
x = Some(10);
if let Some(v) = x {
}
Valori opționale vs. null pointers
“I call it my billion-dollar mistake. [...] This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.” — C. A. R. Hoare
let p = Some(Point::new(2.0, 8.0));
if let Some(Point { x, y }) = p {
}
match p {
Some(Point { x, y }) => {},
None => {},
}
let t = (10, "a");
let (n, s) = t;
enum Option<T> {
None,
Some(T),
}
pub fn add_two(a: i32) -> i32 {
a + 2
}
#[bench]
fn bench_add_two(b: &mut Bencher) {
b.iter(|| add_two(2));
}
$ cargo bench
Compiling hello v0.1.0 (file:///home/grayshade/hello)
Finished release [optimized] target(s) in 0.74 secs
Running target/release/deps/hello-b644eaf5a2174734
running 1 test
test bench_add_two ... bench: 1 ns/iter (+/- 0)
test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured; 0 filtered out
trait Hello {
fn greet(&self);
}
struct Cat;
impl Hello for Cat {
fn greet(&self) {
println!("Meow meow meow meow meow");
}
}
struct Dog;
impl Hello for Dog {
fn greet(&self) {
println!("Woof");
}
}
fn meet<T: Hello>(whom: &T) {
whom.greet();
}
fn main() {
let cat = Cat;
let dog = Dog;
meet(&cat);
meet(&dog);
}
dynamic_cast
, RTTI, destructori
virtuali, ierarhii adânci de clase
clone()
enum Result<T, E> {
Ok(T),
Err(E),
}
fn read_file(file: &Path) -> Result<String, io::Error> {
let mut f = File::open(file)?;
let mut buffer = String::new();
f.read_to_string(&mut buffer)?;
Ok(buffer)
}
errno
, return values, std::error_code
, excepții, setjmp
)
foo(unique_ptr<C>(new C),
unique_ptr<C>(new C));
Spot the bug
fn consume(_: String) {}
let s = String::from("hello");
consume(s);
consume(s);
Va fi f
optimizată la g
?
void f(int *p, int *q) {
*p += *q;
*p += *q;
}
void g(int *p, int *q) {
*p += *q + *q;
}
int x = 10, *p = &x, *q = &x;
f(p, q);
x = 10;
g(p, q);
p
și
q
indică spre valori diferitep
și
q
indică spre valori diferiterestrict
în C (dar nu C++)În Rust valorile au:
🎗️aliasing XOR mutability🎗️
fn borrow(_s: &String) {}
fn mutate(_s: &mut String) {}
fn main() {
let mut s = String::from("hello ");
borrow(&s);
mutate(&mut s);
println!("{}", s);
}
Once
, shared pointers, canale
let (tx, rx) = mpsc::channel();
thread::spawn(move || for i in 0..10 {
tx.send(i).unwrap();
});
for x in rx.iter() {
println!("{}", x);
}
“Anything at all can happen; the Standard imposes no requirements. The program may fail to compile, or it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.”
😱
MutexGuard
vs. Java synchronized
String
, OsString
, CString
bindgen
ripgrep
serde_json
csv
webrender
pathfinder
tantivy
rtfm
class ::String
def blank?
/\A[[:space:]]*\z/ == self
end
end
extern fast_blank(buf: &Buf) -> bool {
buf.as_slice().chars().all(|c| c.is_whitespace())
}
Ruby | 946K iter/s |
C | 10.5M iter/s |
Rust | 11M iter/s |