Diversity w polskim IT
Danny Denenberg
Danny DenenbergSoftware Developer Intern @ Gallup

Rust oczami programisty JavaScript

Sprawdź, jakie spostrzeżenia po poznaniu Rusta ma programista, który na co dzień korzysta z JavaScriptu.
3.10.20194 min
Rust oczami programisty JavaScript

Jakiś czas temu próbowałem znaleźć coś ciekawego do poczytania w sieci. Wtedy wpadłem na Rusta. Rust to:

„Język umożliwiający każdemu tworzenie niezawodnego i wydajnego oprogramowania”.

Krótko mówiąc, to język do programowania systemów. Zadziwiająco szybki. W wielu testach porównawczych, przeprowadzanych przez The Computer Language Benchmarks Game, prędkością prześciga nawet C ++ (głównie w przypadku złożonych zadań algorytmicznych, takich jak drzewa binarne itp.).

Zanim jednak zacząłem zagłębiać się w sam język, sprawdzałem, co ludzie o nim piszą. Rust powstał w 2011 roku i jest wspierany przez Mozillę (non-profit). Ma za sobą nieco niszową grupę, składającą się głównie z byłych programistów C i C++, którzy chcieli oderwać się od NPE, niezdefiniowanych zachowań, złożoności języka, zwariowanych makr itp.

Mimo że Rust wciąż jest bardzo młodym językiem, który wciąż się rozwija, ma już w sieci swoją stronę poświęconą programowaniu gier. Niektóre z gier stworzonych w tym języku są bardzo popularne, a nawet zostały umieszczone w App Store i Google Play Store, np. A Snake's Tale. Rust ma również skutecznego menedżera pakietów - crates.io, który jest porównywalny z npm. Pobrano go już prawie 1,5 miliarda razy.

Po zobaczeniu tego wszystkiego zdecydowałem, że muszę zaspokoić swoją ciekawość i nauczyć się składni Rusta. Zacząłem od przeczytania The Book - kompletnego przewodnika po składni, idiomach i strukturze programów w Rust.

Ponieważ znam wiele języków podobnych do C, składnia była dla mnie prosta i łatwa do zrozumienia. Jeśli jesteś jedną z osób, które używają const, gdy tylko jest to możliwe, i gardzisz tymi, którzy tego nie robią - pokochasz Rusta. Domyślna forma przypisywania zmiennych czyni je niemutowalnymi.

// Below is an immutable variable
let a = 5;// Below is a mutable variable
let mut b = 5;// General form for variables:
let var_name: type = value;


Typy danych w Rust są proste. Liczby całkowite składają się z 8 do 128-bitowych liczb z i bez znaku.


Liczby całkowite

Istnieją również niemutowalne typy tablicowe, znaki, &str (referencję do listy znaków w pamięci), krotki, wyliczenia,
struktury, kolekcje itp. Funkcje deklarowane są za pomocą słowa kluczowego fn:

fn main() {
    println!("Hello, world");
}


Możesz określić zwracane wartości za pomocą symbolu ->, a jeśli zwracasz je w ostatnim wierszu funkcji, to nie ma potrzeby dołączania słowa kluczowego return.

// returns the 32-bit integer 5
fn my_function() -> u32 {
    5
}


Wszystko szło gładko, dopóki nie wpadłem na pojęcie własności (ownership). Wszystkie programy w trakcie działania muszą zarządzać sposobem korzystania z pamięci komputera. Ponieważ Rust nie odśmieca pamięci, a programiści nie muszą ręcznie przydzielać i zwalniać pamięci, pamięcią zarządza system własności.


Oto zasady własności w Rust (bezpośrednio z The Book):

  • Każda wartość w Rust ma zmienną, która nazywa się jej właścicielem.
  • Jednocześnie może istnieć tylko jeden właściciel.
  • Gdy właściciel wypadnie z zasięgu, wartość zostanie usunięta.


Spójrzmy na przykład:

{                      // s is not valid here, it’s not yet declared
    let s = "hello";   // s is valid from this point forward

    // do stuff with s
}                      // this scope is now over, and s is no longer valid


Tak przyblokowałem się, pierwszy raz używając Rusta.

let a = String::from("Hello, world!"); // a is the owner
let b = a; // ownership has changed to b. What is a?

println!("{}", a); // error[E0382]: borrow of moved value: `a`


Ponieważ jednocześnie może istnieć tylko jeden właściciel, nie mogę przypisać wartości zmiennej innemu, używając nazwy pierwszej zmiennej, jeśli została ona przydzielona w stercie, tak jak String w Rust. Teraz, jeśli typ zmiennej jest prymitywny (int, double, bool itp.), ponowne przypisanie po prostu skopiuje wartość i NIE zmieni właściciela.

Odwołując się do zmiennej, używasz symbolu & jak w C i C++. Referencje pozwalają programiście pobrać wartość bez przejmowania własności. W jednym czasie może istnieć tyle niemutowalnych referencji ile chcesz, ale tylko JEDNA mutowalna referencja.

let a = String::from("Dude, Rust is sick.");
{
    let b = &a; // ok
    let c = &a; // ok
}

{
    let b = &mut a; // mutable reference. ok.
    *b = String::from("Different!"); // change value. ok
}

{
    let b = &mut a; // ok
    let c = &mut a; // ERROR. Only one mut reference at a time!
}


Jeszcze trudniejszy do zrozumienia jest dla mnie czas życia (lifetime), czyli koncept, dzięki któremu Rust nie musi używać garbage collectora. Jest to również rozwiązanie znanego problemu C++ - zwisających wskaźników (dangling pointers), gdy zmienna jest „używana po zwolnieniu”. Nie będę nawet próbował tu wyjaśniać tej koncepcji. Więcej znajdziesz tutaj.

Ogólnie rzecz biorąc, moje doświadczenie z Rustem było satysfakcjonujące. Z łatwością zrozumiałem jego składnię i wytyczne dotyczące stylu. Muszę przyznać, że niektóre koncepcje były początkowo trudne do zrozumienia. Nie wiem, czy to tylko moje spostrzeżenie, ale nawet kod napisany w Ruście wygląda elegancko. 

Rust wykorzystuje funkcyjne techniki programowania, powszechnie stosowane w JavaScript (filtrowanie, mapowanie itp.), a słowa kluczowe składni są krótkie i konkretne (fn, enum, let, mut, i32 i str).

Niektórzy programiści nawołują, aby Rust był kolejnym C albo C++. Nie wiem, czy dojdzie do tego w najbliższym czasie, ale jedno jest pewne - Rust będzie rósł i dojrzewał jako język. W końcu ma wsparcie Mozilli i „kult” odziedziczony po programistach C++, którzy mogli by za niego zabić.


Oryginał tekstu w języku angielskim przeczytasz tutaj.

<p>Loading...</p>