Rust - następca języka C?

Przez lata ludzie stworzyli setki różnych języków programowania. Obecnie praktycznie całe oprogramowanie na świecie jest tworzone wyłącznie za pomocą kilku z nich. Do czołówki najpopularniejszych należą C, C++, Java, C#, Python i JavaScript. Swoich zwolenników mają też jednak języki mniej znane takie jak Scala, Haskell, Go czy Rust. W tym artykule przyjrzymy się właśnie temu ostatniemu. 

Trochę historii

Rust pojawił się po raz pierwszy w 2010 i od tamtej pory jest rozwijany przez Mozillę. Główną ideą języka jest duże bezpieczeństwo związane między innymi z zarządzaniem pamięcią i programowaniem współbieżnym. Przez ostatnie cztery lata, Rust był co roku wybierany jako „najbardziej lubiany” język programowania w ankiecie przeprowadzanej wśród użytkowników serwisu Stack Overlow.

Niedawno pojawiły się obawy związane z przyszłością Rusta, gdyż ze względu na pandemię Covid-19 Mozilla zwolniła większość osób zajmujących się jego. Osoby związane z projektem zapowiedziały utworzenie „Fundacji Rusta”, co ma pomóc uniezależnić jego rozwój od Mozilli. Do tego swoją gotowość do wsparcia rozwoju Rusta zgłosił niedawno AWS Amazona pisząc, że odnosi duże korzyści z pracy z językiem, który jest jednocześnie wydajny jak i bezpieczny,.

Jak zacząć?

Postawienie pierwszych kroków z Rustem dla osoby obeznanej już z oprogramowaniem nie jest bardzo trudne. Najprościej wejść na oficjalną stronę języka, gdzie można ściągnąć narzędzia do kompilacji i zarządzania pakietami, a nawet znaleźć elektroniczną wersję książki o podstawach Rusta.

Język nie ma żadnego „dedykowanego IDE” jak np. PyCharm, ale za to dość łatwo integruje się z moim ulubionym środowiskiem, czyli Visual Studio Code.  Poniżej możesz zobaczyć jak wygląda napisany w Ruście program typu „Hello, world!”:

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

Język dla paranoików?

Twórcy Rusta postawili sobie za cel stworzenie języka cechującego się dużym bezpieczeństwem. Stąd można w nim znaleźć sporo nietypowych rozwiązań, które wymuszają na programiście unikanie niebezpiecznych praktyk. Wymieńmy sobie kilka z nich.

 

Zmienne mutowalne i niemutowalne

Koncpecja zmiennych mutowalnych i niemutowalnych nie jest charakterystyczna jedynie dla Rusta. Można ją spotkać np. w Pythonie. Ciekawe jest jednak to, że pisząc w Ruście każda zmienna jest domyślnie tworzona jako niemutowalna, a więc nie można zmieniać jej wartości. Utworzenie zmiennej mutowalnej trzeba wyraźnie zaznaczyć słowem kluczowym mut. Pokazuje to poniższy kod:

 

    let x = 1;
    x = 2; // Ten kod wygeneruje błąd

    let mut y = 1;
    y = 2; // Ten kod zadziała poprawnie
Własność danych

Rust bardzo rygorystycznie podchodzi do zarządzania pamięcią. Język nie ma garbage collectora, a pamięć przydzielona do danych jest zwalniana w momencie, w którym program wychodzi poza zakres widoczności tych danych. Podobnie jest w programach napisanych w C++ zgodnie z metodologią RAII, w tym wypadku jednak wdrożone są dodatkowe mechanizmy nazywane „własnością danych” (ang. ownership), które mają uniemożliwić napisanie programów w błędny sposów (co jest zmorą programistów C++).

Mechanizmy te są jednak dość mało intuicyjne dla osób, które pierwszy raz zetknęły się z Rustem. Np. poniższy program nie skompiluje się:

fn main() {
    let str1 = String::from("Hello");
    let str2 = str1;

    println!("{}", str2); // Ta linijka jest poprawna
    println!("{}", str1); // Ta linijka spowoduje błąd kompilacji
}

Przyczyną jest to, że typ String zawiera dynamicznie alokowane dane, do których wskaźnik jest kopiowany w momencie przepisania wartoście zmiennej str1 do str2. W efekcie, gdyby jedna z tych zmiennych miała szerszy zakres widoczności od drugiej, to pamięć zostałaby przedwcześnie zwolniona. Z tego powodu po przepisaniu str1 do str2 zmienna str1 przestaje być poprawna. Rust wyłapie próbę jej użycia już na etapie kompilacji. 

Inne mechanizmy języka

Ciekawych cech języka Rust jest oczywiście więcej. Można do nich zaliczyć np. rezygnację z wartości typu NULL i zastąpienie jej tzw. opcjami, które wymuszają tworzenie kodu obsługujące referencje nie wskazujące na żadne dane. Ciekawie rozwiązany jest też system obsługi błędów odbiegający od znanych z innych języków wyjątków.

Menedżer pakietów

Obecnie systemy zarządzania zależnościami stają się integralną częścią nowoczesnych języków programowania. Rust również jest dostarczany razem z menedżerem pakietów o nazwie Cargo. Pozwala on na wygodne zarządzanie tworzonym kodem i korzystanie z repozytorium pakietów. Narzędzie umożliwia również zarządzanie tworzeniem i kompilacją projektów. Pod tym względem przypomina ono NPM dla Node.js.

Trochę bardziej złożony program

Dla przykładu chciałbym pokazać Ci jeszcze dwa proste programy realizujące komunikację przez protokół TCP. Aplikacja klienta odczytuje z wiersza poleceń dane i przesyła je do serwera, który wyświetla dane w konsoli. 

Kod serwera:

use std::net::TcpListener;
use std::io::prelude::*;

fn main()
{
    let listener = TcpListener::bind("127.0.0.1:7878")
    .expect("Cannot create TCP listener");

    println!("Server is running");

    for stream in listener.incoming()
    {
        println!("Client connected");

        let mut stream =  stream
        .expect("Cannot get network stream");
        
        loop
        {
            let mut buffer : [u8; 1024] = [0; 1024];
            match stream.read(&mut buffer)
            {
                Ok(_) => println!("Client: {}", String::from_utf8_lossy(&buffer[..])),
                Err(_) => 
                {
                    println!("Client disconnected");
                    break;
                }
            }
        }
    };
}

Kod klienta:

use std::net::TcpStream;
use std::io;
use std::io::prelude::*;


fn main() 
{
    let mut stream = TcpStream::connect("127.0.0.1:7878")
    .expect("Cannot connect to server");

    loop
    {
        println!("Enter message:");

        let mut message = String::new();

        io::stdin().read_line(&mut message)
        .expect("Failed to read line");

        let buf = message.as_bytes();
        stream.write(buf)
        .expect("Error during sending data");
    }
}

Podsumowanie

Rust jest językiem, którego przeznaczeniem ma być tworzenie wydajnych aplikacji. Ma więc służyć do programowania systemowego. Co ciekawe pojawiły się nawet projekty systemów operacyjnych napisane w tym języku.

Jednocześnie Rust został opracowany tak, że uniemożliwia stosowanie wielu niebezpiecznych praktyk możliwych w pracy z językami C i C++. Niestety komplikuje to bardzo sam język.

O ile np. język C uważam za jeden z najprostszych języków jakie istnieją i bardzo dobry dla początkujących progamistów (chodzi o zrozumienie zasad jego działania, a nie samo posługiwanie się nim, polecam mój wpis „Czy warto się uczyć języka C?”), to Rusta nie poleciłbym absolutnie osobie, która nie miała nigdy styczności z programowaniem.

Mam wrażenie, że warto się za niego zabrać po kilku latach pracy z innymi językami programowania. Dopiero wtedy da się zrozumieć motywacje stojące za wieloma rozwiązaniami Rusta, które mają zabezpieczyć programistę przed różnymi błędami. Dla osoby początkującej będą one tylko niezrozumiałym komplikowaniem języka.

Ze względu na dużą popularność w społeczności programistów i wykorzystanie w kilku dużych projektach warto śledzić dalszy rozwój tego języka.

Maciej Kraszewski

Maciej Kraszewski

Inżynier, menedżer R&D i nauczyciel akademicki. Uwielbiam zajmować się tworzeniem nowych technologii, zdobywaniem nowej wiedzy i dzieleniem się swoim doświadczeniem z innymi. Specjalizuję się w zagadnieniach przetwarzania obrazu i widzenia maszynowego.
Szukasz dobrych materiałów o projektowaniu elektroniki?

Załóż darmowe konto na naszej platformie i odbierz pakiet materiałów edukacyjnych.

Zakładając konto zgadzasz się na przesyłanie Ci treści marketingowych przez IT20 sp. z o.o. zgodnie z dostępną na stronie Polityką Prywatności. Możesz wycofać zgodę w każdej chwili.

One thought on “Rust – następca języka C?

  • 3 września 2021 o 20:14
    Permalink

    Czy planuje Pan przygotowanie kursu z tego języka?

    Odpowiedz

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Szukasz dobrych materiałów o projektowaniu elektroniki?

Załóż darmowe konto na naszej platformie i odbierz pakiet materiałów edukacyjnych.

Zakładając konto zgadzasz się na przesyłanie Ci treści marketingowych przez IT20 sp. z o.o. zgodnie z dostępną na stronie Polityką Prywatności. Możesz wycofać zgodę w każdej chwili.

Zapisz się na listę mailową i odbierz swoje bonusy!

Więcej treści na temat elektroniki i robotyki, darmowe e-booki i dostęp do minikursów on-line. Otrzymasz to wszystko zapisując się na naszą listę mailową.