Rust
08.05.2015
Serdar Doğruyol
Lead Backend Developer at Protel, Rubyist, Rustacean
Twitter: @sdogruyol
Github: www.github.com/sdogruyol
Blog: www.serdardogruyol.com
Rust is a systems programming language that runs blazingly fast, prevents almost all crashes, and eliminates data races.
Tarihçe
- 2009 yılında Graydon Hoare tarafından geliştirilmeye başlandı.
- 2010 yılında Mozilla projeye sponsor oldu
- Tamamen açık kaynak olarak geliştiriliyor ve geliştiricilerin çoğu topluluktan.
- Cyclone, Haskell, Erlang, Ruby, ML vb. dillerden etkilenilerek geliştirildi.
Neden?
Hızlı
Güvenli
Pratik
Düşük Seviye
Performans
Benchmark
Rust: 69941
Jruby: 27441
Ruby (MRI): 9612
OS,Kernel
C / C++
- zero-cost abstractions
- move semantics
- guaranteed memory safety
- threads without data races
- trait-based generics
- pattern matching
- type inference
- efficient C bindings
- cross-platform
15 Mayıs
1.0.0
Kod zamanı!
Hello World
fn main() {
println!("Hello, world!");
}
rustc hello.rs
./main # or main.exe for windows
Çalıştıralım
Değişkenler
fn main() {
let x = 5; // Type inference
let y: i32 = 10; // Type specified
let (a, b) = (1, 2); // Pattern Matching
}
Değişkenler default olarak immutable
fn main() {
let x = 5;
x = 10;
}
error: re-assignment of immutable variable `x`
x = 10;
^~~~~~~
Derlemeye çalıştığınızda compile time hatası alırsınız
Mutable yapmak için
fn main() {
let mut x = 5;
x = 10;
}
Fonksiyonlar
fn main() {
}
main fonksiyonu her Rust programında var
fn print_sum(x: i32, y: i32) {
println!("sum is: {}", x + y);
}
fn add_one(x: i32) -> i32 {
x + 1
}
Fonksiyon parametlerinde tip olmak zorunda
Dönüş tipi -> şeklinde belirtilir
If
let x = 5;
if x == 5 {
println!("x is five!");
} else {
println!("x is not five :(");
}
let x = 5;
let y = if x == 5 {
10
} else {
15
};
Tipik bir programlama dilinde olduğu gibi
Hatta şu şekilde yazılabilir.
let x = 5;
let y = if x == 5 { 10 } else { 15 }; // y: i32
Aslında If bir expression ( Ruby gibi)
For
for x in 0..10 {
println!("{}", x); // x: i32
}
for var in expression {
code
}
Dinamik bir programlama diline benziyor.
Şart bir expression olabilir
While
let mut x = 5; // mut x: u32
let mut done = false; // mut done: bool
while !done {
x += x - 3;
println!("{}", x);
if x % 5 == 0 {
done = true;
}
}
let mut x = 5;
loop {
x += x - 3;
println!("{}", x);
if x % 5 == 0 { break; }
}
Struct
struct Point {
x: i32,
y: i32,
}
fn main() {
let origin = Point { x: 0, y: 0 }; // origin: Point
println!("The origin is at ({}, {})", origin.x, origin.y);
}
C'deki ile benzer.
Kompleks veri yapılarını Struct sayesinde modelliyoruz.
Ownership
{
int *x = malloc(sizeof(int));
// we can now do stuff with our handle x
*x = 5;
free(x);
}
{
let x = Box::new(5);
}
Rust
C
Rust bizim için memory alloc ve dealloc işini hallediyor. Dolayısı ile unutma ihtimalimiz sıfır.
Ownership
fn main() {
let x = Box::new(5);
add_one(x);
println!("{}", x);
}
fn add_one(mut num: Box<i32>) {
*num += 1;
}
error: use of moved value: `x`
println!("{}", x);
^
Peki nasıl çözeceğiz?
Compiler derlememize izin vermiyor.
Ownership
fn main() {
let x = Box::new(5);
let y = add_one(x);
println!("{}", y);
}
fn add_one(mut num: Box<i32>) -> Box<i32> {
*num += 1;
num
}
Ownership geri veriliyor
Borrowing
fn main() {
let mut x = 5;
add_one(&mut x);
println!("{}", x);
}
fn add_one(num: &mut i32) {
*num += 1;
}
Box oluşturulmadan değer fonksiyona ödünç veriliyor ve çalışma bittikten sonra geri veriliyor.
Lifetime
- I acquire a handle to some kind of resource.
- I lend you a reference to the resource.
- I decide I'm done with the resource, and deallocate it, while you still have your reference.
- You decide to use the resource.
SEGFAULT
Lifetime
fn add_one(num: &mut i32) {
*num += 1;
}
fn add_one<'a>(num: &'a mut i32) {
*num += 1;
}
Lifetime elision
struct Foo<'a> {
x: &'a i32,
}
fn main() {
let y = &5;
let f = Foo { x: y };
println!("{}", f.x);
}
Struct with Lifetime
Lifetime
struct Foo<'a> {
x: &'a i32,
}
fn main() {
let x; // -+ x goes into scope
// |
{ // |
let y = &5; // ---+ y goes into scope
let f = Foo { x: y }; // ---+ f goes into scope
x = &f.x; // | | error here
} // ---+ f and y go out of scope
// |
println!("{}", x); // |
}
Compile time error
Lifetime Ellision
-
Each elided lifetime in a function's arguments becomes a distinct lifetime parameter.
-
If there is exactly one input lifetime, elided or not, that lifetime is assigned to all elided lifetimes in the return values of that function.
-
If there are multiple input lifetimes, but one of them is &self or &mut self, the lifetime of self is assigned to all elided output lifetimes.
Shared Ownership
struct Car {
name: String,
}
struct Wheel {
size: i32,
owner: Car,
}
fn main() {
let car = Car { name: "DeLorean".to_string() };
for _ in 0..4 {
Wheel { size: 360, owner: car };
}
}
error: use of moved value: `car`
Wheel { size: 360, owner: car };
^~~
note: `car` moved here because it has type `Car`, which is non-copyable
Wheel { size: 360, owner: car };
Shared Ownership
use std::rc::Rc;
struct Car {
name: String,
}
struct Wheel {
size: i32,
owner: Rc<Car>,
}
fn main() {
let car = Car { name: "DeLorean".to_string() };
let car_owner = Rc::new(car);
for _ in 0..4 {
Wheel { size: 360, owner: car_owner.clone() };
}
}
..ve daha fazlası
Lifetime
Generics
Traits
Macros
Unsafe
Inline Assembly
Kaynaklar
Sorular?
Teşekkürler
@sdogruyol
Rust
By Serdar Dogruyol
Rust
- 1,524