Programowanie w języku Rust. Oficjalny podręcznik - ebook
Programowanie w języku Rust. Oficjalny podręcznik - ebook
Rust świetnie się sprawdza na poziomie systemowym, czyli z niskopoziomowymi szczegółami zarządzania pamięcią, reprezentacji danych i współbieżności. Jest zaprojektowany tak, aby naturalnie pisać niezawodny i wydajny kod. Język ten jest również wystarczająco ekspresyjny i ergonomiczny, aby umożliwiać tworzenie aplikacji CLI czy serwerów WWW. Łatwo dostrzec, że praca z Rustem pozwala budować umiejętności, które przydają się w wielu dziedzinach programowania.
Ta książka jest oficjalnym przewodnikiem po języku programowania systemów Rust, udostępnianym na licencji open source. Dzięki niej nauczysz się pisać szybsze i bardziej niezawodne oprogramowanie. Dowiesz się również, jak zapewnić sobie kontrolę nad niskopoziomowymi szczegółami wraz z wysokopoziomową ergonomią, co pozwoli Ci na zwiększenie produktywności i uniknięcie trudności związanych z językami niskiego poziomu. Oprócz przystępnie przekazanej wiedzy i niezliczonych przykładów kodu w książce znalazły się trzy rozdziały poświęcone budowaniu kompletnych projektów: gry w zgadywanie liczb, rustowej implementacji narzędzia wiersza poleceń i serwera wielowątkowego.
W książce między innymi:
- tworzenie funkcji, wybieranie typów danych i wiązanie zmiennych
- własność i pożyczanie, czasy życia, typy sparametryzowane
- przekazywanie kompilatorowi ograniczeń programu
- bezstresowe stosowanie współbieżności
- Cargo - wbudowany menedżer pakietów Rusta
- testowanie, obsługa błędów, refaktoryzacja i ekspresyjne dopasowywanie wzorców
Rust: język przyszłości programowania!
Spis treści
Przedmowa
Wstęp
Podziękowania
Wprowadzenie
1. Pierwsze kroki
- Instalacja
- Instalowanie narzędzia rustup w systemie Linux lub macOS
- Instalowanie narzędzia rustup w systemie Windows
- Rozwiązywanie problemów
- Aktualizowanie i odinstalowywanie
- Lokalna dokumentacja
- Witaj, świecie!
- Tworzenie katalogu projektu
- Pisanie i uruchamianie programu Rusta
- Anatomia programu Rusta
- Kompilowanie i uruchamianie to oddzielne kroki
- Witaj, Cargo!
- Tworzenie projektu za pomocą Cargo
- Kompilowanie i uruchamianie projektu Cargo
- Kompilowanie w celu wydania projektu
- Cargo jako konwencja
- Podsumowanie
2. Programowanie gry w zgadywanie
- Konfigurowanie nowego projektu
- Przetwarzanie zgadywania
- Przechowywanie wartości za pomocą zmiennych
- Odbieranie danych wprowadzanych przez użytkownika
- Obsługa ewentualnego niepowodzenia za pomocą typu Result
- Wypisywanie wartości za pomocą symboli zastępczych println!
- Testowanie pierwszej części
- Generowanie sekretnej liczby
- Korzystanie ze skrzynki w celu uzyskania większej funkcjonalności
- Generowanie liczby losowej
- Porównywanie próby odgadnięcia z sekretną liczbą
- Umożliwianie wielokrotnego zgadywania dzięki zastosowaniu pętli
- Zakończenie gry po odgadnięciu prawidłowej liczby
- Obsługa nieprawidłowych danych wejściowych
- Podsumowanie
3. Powszechne koncepcje programowania
- Zmienne i mutowalność
- Stałe
- Przysłanianie
- Typy danych
- Typy skalarne
- Typy złożone
- Funkcje
- Parametry
- Instrukcje i wyrażenia
- Funkcje z wartościami zwracanymi
- Komentarze
- Przepływ sterowania
- Wyrażenia if
- Powtarzanie za pomocą pętli
- Podsumowanie
4. Własność
- Czym jest własność?
- Reguły własności
- Zakres zmiennych
- Typ String
- Pamięć i alokacja
- Własność i funkcje
- Wartości zwracane i zakres
- Referencje i pożyczanie
- Referencje mutowalne
- Referencje wiszące
- Reguły referencji
- Typ wycinka
- Wycinki łańcucha znaków
- Inne wycinki
- Podsumowanie
5. Wykorzystanie struktur do organizowania powiązanych ze sobą danych
- Definiowanie struktur i tworzenie ich instancji
- Użycie skrótu inicjowania pól
- Tworzenie instancji z innych instancji za pomocą składni aktualizacji struktury
- Tworzenie różnych typów za pomocą struktur krotkowych bez nazwanych pól
- Struktury jednostkowe bez żadnych pól
- Przykładowy program wykorzystujący struktury
- Refaktoryzacja z wykorzystaniem krotek
- Refaktoryzacja z wykorzystaniem struktur: dodanie znaczenia
- Dodanie użytecznej funkcjonalności za pomocą cech pochodnych
- Składnia metod
- Definiowanie metod
- Metody z większą liczbą parametrów
- Funkcje powiązane
- Wiele bloków impl
- Podsumowanie
6. Typy wyliczeniowe i dopasowywanie wzorców
- Definiowanie typu wyliczeniowego
- Wartości wyliczenia
- Enumeracja Option i jej zalety w porównaniu z wartościami zerowymi
- Konstrukcja match przepływu sterowania
- Wzorce, które powodują powiązanie z wartościami
- Dopasowywania za pomocą Option<T>
- Dopasowywania są wyczerpujące
- Wzorce catch-all i symbol zastępczy _
- Zwięzły przepływ sterowania z wykorzystaniem składni if let
- Podsumowanie
7. Zarządzanie rozwijającymi się projektami za pomocą pakietów, skrzynek i modułów
- Pakiety i skrzynki
- Definiowanie modułów w celu kontrolowania zakresu i prywatności
- Ścieżki odwoływania się do elementów w drzewie modułów
- Udostępnianie ścieżek za pomocą słowa kluczowego pub
- Rozpoczynanie ścieżek względnych od słowa kluczowego super
- Upublicznianie struktur i wyliczeń
- Wprowadzanie ścieżek do zakresu za pomocą słowa kluczowego use
- Tworzenie idiomatycznych ścieżek use
- Wprowadzanie nowych nazw za pomocą słowa kluczowego as
- Ponowne eksportowanie nazw za pomocą pub use
- Korzystanie z pakietów zewnętrznych
- Skracanie długich list instrukcji use za pomocą zagnieżdżonych ścieżek
- Operator glob
- Rozdzielanie modułów na różne pliki
- Podsumowanie
8. Powszechnie używane kolekcje
- Przechowywanie list wartości za pomocą wektorów
- Tworzenie nowego wektora
- Aktualizowanie wektora
- Odczytywanie elementów wektorów
- Iterowanie przez wartości w wektorze
- Przechowywanie wielu typów za pomocą wyliczenia
- Porzucenie wektora powoduje porzucenie jego elementów
- Wykorzystywanie typu String do przechowywania tekstu zakodowanego w UTF-8
- Czym jest String?
- Tworzenie nowej instancji String
- Aktualizowanie instancji String
- Indeksowanie wartości String
- Tworzenie wycinków wartości String
- Metody iterowania przez wartości String
- Typy String nie są takie proste
- Przechowywanie kluczy z powiązanymi wartościami w mapach mieszających
- Tworzenie nowej instancji HashMap
- Uzyskiwanie dostępu do wartości z mapy mieszającej
- Mapy mieszające i własność
- Aktualizowanie instancji HashMap
- Funkcje mieszające
- Podsumowanie
9. Obsługa błędów
- Obsługa błędów nieodwracalnych za pomocą wywołania panic!
- Obsługa błędów odwracalnych z wykorzystaniem typu Result
- Dopasowywanie na podstawie różnych błędów
- Propagacja błędów
- Panikować czy nie panikować?
- Przykłady, kod prototypów i testy
- Przypadki, w których mamy więcej informacji niż kompilator
- Wskazówki dotyczące obsługi błędów
- Tworzenie typów niestandardowych do celów walidacji
- Podsumowanie
10. Typy sparametryzowane, cechy i czasy życia
- Redukowanie duplikacji przez wyodrębnianie funkcji
- Sparametryzowane typy danych
- Typy sparametryzowane w definicjach funkcji
- Typy sparametryzowane w definicjach struktur
- Typy sparametryzowane w definicjach wyliczeń
- Typy sparametryzowane w definicjach metod
- Wydajność kodu wykorzystującego typy sparametryzowane
- Cechy - definiowanie współdzielonego zachowania
- Definiowanie cechy
- Implementowanie cechy w typie
- Implementacje domyślne
- Cechy jako parametry
- Zwracanie typów, które implementują cechy
- Używanie wiązań cech do warunkowego implementowania metod
- Walidacja referencji za pomocą czasów życia
- Używanie czasów życia do zapobiegania powstawaniu wiszących referencji
- Kontrola pożyczania
- Sparametryzowane czasy życia w funkcjach
- Składnia adnotacji czasów życia
- Adnotacje czasów życia w sygnaturach funkcji
- Myślenie w kategoriach czasów życia
- Adnotacje czasów życia w definicjach struktur
- Elizja czasów życia
- Adnotacje czasów życia w definicjach metod
- Statyczny czas życia
- Parametry typów sparametryzowanych, wiązania cech i czasy życia razem wzięte
- Podsumowanie
11. Pisanie zautomatyzowanych testów
- Jak pisać testy?
- Anatomia funkcji testowej
- Sprawdzenie wyników za pomocą makra assert!
- Testowanie równości za pomocą makr assert_eq! i assert_ne!
- Dodawanie niestandardowych komunikatów o błędach
- Sprawdzanie paniki za pomocą atrybutu should_panic
- Wykorzystanie w testach typu Result<T, E>
- Kontrolowanie sposobu uruchamiania testów
- Uruchamianie testów równolegle lub po kolei
- Wyświetlanie danych wyjściowych funkcji
- Uruchamianie podzbioru testów według nazwy
- Ignorowanie niektórych testów i uruchamianie ich na specjalne żądanie
- Organizowanie testów
- Testy jednostkowe
- Testy integracyjne
- Podsumowanie
12. Projekt z wykorzystaniem operacji we-wy - budowanie programu wiersza poleceń
- Przyjmowanie argumentów wiersza poleceń
- Odczytywanie wartości argumentów
- Zapisywanie wartości argumentów w zmiennych
- Odczyt pliku
- Refaktoryzacja w celu poprawy modułowości i obsługi błędów
- Separacja zagadnień projektów binarnych
- Naprawianie obsługi błędów
- Wyodrębnianie logiki z funkcji main
- Wydzielanie kodu do skrzynki biblioteki
- Rozwijanie funkcjonalności biblioteki za pomocą programowania opartego na testach
- Pisanie testu kończącego się niepowodzeniem
- Pisanie kodu w celu zapewnienia pozytywnego wyniku testu
- Praca ze zmiennymi środowiskowymi
- Pisanie niepomyślnego testu dla funkcji search nieuwzględniającej wielkości liter
- Implementacja funkcji search_case_insensitive
- Wypisywanie komunikatów o błędach do standardowego strumienia błędów, a nie do standardowego strumienia wyjściowego
- Sprawdzanie, gdzie są zapisywane błędy
- Wypisywanie błędów do standardowego strumienia błędów
- Podsumowanie
13. Cechy języka funkcyjnego - iteratory i domknięcia
- Domknięcia - funkcje anonimowe, które przechwytują swoje środowisko
- Przechwytywanie środowiska za pomocą domknięć
- Inferowanie i adnotowanie typu domknięcia
- Przechwytywanie referencji lub przenoszenie własności
- Przenoszenie przechwyconych wartości z domknięć i cechy Fn
- Przetwarzanie serii elementów za pomocą iteratorów
- Cecha Iterator i metoda next
- Metody, które konsumują iterator
- Metody, które wytwarzają inne iteratory
- Używanie domknięć, które przechwytują swoje środowisko
- Ulepszenie projektu operacji we-wy
- Usuwanie clone przy użyciu iteratora
- Zwiększanie czytelności kodu dzięki adapterom iteratora
- Wybór pomiędzy pętlami i iteratorami
- Porównanie wydajności pętli i iteratorów
- Podsumowanie
14. Narzędzie Cargo i rejestr crates.io
- Dostosowywanie kompilacji za pomocą profili wydania
- Publikowanie skrzynki w rejestrze Crates.io
- Tworzenie przydatnych komentarzy dokumentujących
- Eksportowanie wygodnego publicznego API za pomocą pub use
- Zakładanie konta w rejestrze Crates.io
- Dodawanie metadanych do nowej skrzynki
- Publikowanie w rejestrze Crates.io
- Publikowanie nowej wersji istniejącej skrzynki
- Dezaktualizowanie wersji z Crates.io za pomocą polecenia cargo yank
- Obszary robocze Cargo
- Tworzenie obszaru roboczego
- Tworzenie drugiego pakietu w obszarze roboczym
- Instalowanie plików binarnych za pomocą polecenia cargo install
- Rozszerzanie Cargo przy użyciu niestandardowych poleceń
- Podsumowanie
15. Inteligentne wskaźniki
- Używanie Box<T> do wskazywania danych na stercie
- Używanie Box<T> do przechowywania danych na stercie
- Zastosowanie boksów do używania typów rekurencyjnych
- Wykorzystanie cechy Deref do traktowania inteligentnych wskaźników jak regularnych referencji
- Podążanie za wskaźnikiem do wartości
- Używanie Box<T> jak referencji
- Definiowanie własnego inteligentnego wskaźnika
- Implementacja cechy Deref
- Domyślne wymuszenie wyłuskania w funkcjach i metodach
- Jak wymuszenie wyłuskania współdziała z mutowalnością?
- Wykorzystanie cechy Drop do uruchamiania określonego kodu przy czyszczeniu
- Rc<T> - inteligentny wskaźnik zliczania referencji
- Używanie Rc<T> do udostępniania danych
- Klonowanie Rc<T> zwiększa liczbę referencji
- RefCell<T> i wzorzec mutowalności wewnętrznej
- Egzekwowanie reguł pożyczania w czasie wykonywania za pomocą RefCell<T>
- Mutowalność wewnętrzna - mutowalne pożyczanie niemutowalnej wartości
- Wykorzystanie typów Rc<T> i RefCell<T>, aby mutowalne dane mogły mieć wielu właścicieli
- Cykle referencji mogą powodować wycieki pamięci
- Tworzenie cyklu referencji
- Zapobieganie cyklom referencji za pomocą typu Weak<T>
- Podsumowanie
16. Nieustraszona współbieżność
- Używanie wątków do jednoczesnego uruchomienia kodu
- Tworzenie nowego wątku za pomocą funkcji spawn
- Wykorzystanie uchwytów metody join w celu zaczekania na zakończenie wszystkich wątków
- Używanie domknięć move z wątkami
- Używanie przekazywania komunikatów do przesyłania danych między wątkami
- Kanały i przeniesienie własności
- Wysyłanie wielu wartości i obserwowanie czekającego odbiornika
- Tworzenie wielu producentów przez klonowanie nadajnika
- Współbieżność stanu współdzielonego
- Używanie muteksów w celu umożliwienia dostępu do danych z jednego wątku na raz
- Podobieństwa między typami RefCell<T> i Rc<T> a Mutex<T> i Arc<T>
- Rozszerzanie funkcjonalności współbieżności za pomocą cech Send i Sync
- Umożliwienie przenoszenia własności między wątkami za pomocą cechy Send
- Umożliwianie dostępu z wielu wątków za pomocą cechy Sync
- Ręczne implementowanie cech Send i Sync jest niezabezpieczone
- Podsumowanie
17. Funkcjonalności programowania obiektowego
- Cechy języków obiektowych
- Obiekty zawierają dane i zachowania
- Hermetyzacja, która ukrywa szczegóły implementacji
- Dziedziczenie jako system typów i współdzielenie kodu
- Używanie obiektów cech, które umożliwiają stosowanie wartości różnych typów
- Definiowanie cech typowego zachowania
- Implementowanie cechy
- Obiekty cech wykonują dynamiczną dyspozycję
- Implementacja obiektowego wzorca projektowego
- Definiowanie struktury Post i tworzenie nowej instancji w stanie Draft
- Przechowywanie tekstu treści wpisu
- Upewnianie się, że treść wersji roboczej wpisu jest pusta
- Żądanie korekty zmienia stan wpisu
- Dodanie metody approve w celu zmiany zachowania metody content
- Kompromisy wzorca stanu
- Podsumowanie
18. Wzorce i dopasowywanie
- Wszystkie miejsca, w których można używać wzorców
- Ramiona wyrażenia match
- Wyrażenia warunkowe if let
- Pętle warunkowe while let
- Pętle for
- Instrukcje let
- Parametry funkcji
- Odrzucalność - czy dopasowywanie wzorca może się nie powieść?
- Składnia wzorców
- Dopasowywanie literałów
- Dopasowywanie zmiennych nazwanych
- Wiele wzorców
- Dopasowywanie przedziałów wartości za pomocą ..=
- Destrukturyzacja w celu rozkładania wartości na poszczególne elementy
- Ignorowanie wartości we wzorcu
- Dodatkowe wyrażenia warunkowe ze strażnikami dopasowywania
- Wiązanie za pomocą operatora @
- Podsumowanie
19. Funkcjonalności zaawansowane
- Niezabezpieczony Rust
- Niezabezpieczone supermoce
- Wyłuskiwanie surowego wskaźnika
- Wywoływanie niezabezpieczonej funkcji lub metody
- Uzyskiwanie dostępu do mutowalnej zmiennej statycznej lub modyfikowanie jej
- Implementowanie niezabezpieczonej cechy
- Uzyskiwanie dostępu do pól typu unii
- Kiedy korzystać z niezabezpieczonego kodu?
- Cechy zaawansowane
- Typy powiązane
- Domyślne parametry typu sparametryzowanego i przeciążanie operatora
- Rozróżnianie metod o tej samej nazwie
- Korzystanie z supercech
- Używanie wzorca newtype do implementowania cech zewnętrznych
- Typy zaawansowane
- Używanie wzorca newtype dla zapewnienia bezpieczeństwa typów i warstwy abstrakcji
- Tworzenie synonimów typów za pomocą aliasów typów
- Typ never, który nigdy nie zwraca wartości
- Typy o dynamicznie ustalanych rozmiarach i cecha Sized
- Zaawansowane funkcje i domknięcia
- Wskaźniki funkcji
- Zwracanie domknięć
- Makra
- Różnica między makrami i funkcjami
- Makra deklaratywne z konstrukcją macro_rules! dla metaprogramowania ogólnego
- Makra proceduralne do generowania kodu z atrybutów
- Jak napisać niestandardowe makro derive?
- Makra atrybutowe
- Makra funkcyjne
- Podsumowanie
20. Projekt końcowy - budowa wielowątkowego serwera WWW
- Tworzenie jednowątkowego serwera WWW
- Nasłuchiwanie połączenia TCP
- Odczytywanie żądania
- Analiza żądania HTTP
- Pisanie odpowiedzi
- Zwracanie prawdziwego HTML-a
- Walidacja żądania i selektywne odpowiadanie
- Odrobina refaktoryzacji
- Przekształcenie serwera jednowątkowego w wielowątkowy
- Symulowanie powolnego żądania
- Zwiększenie przepustowości przy użyciu puli wątków
- Eleganckie zamykanie i czyszczenie
- Implementacja cechy Drop w typie ThreadPool
- Sygnalizowanie wątkom, aby przestały nasłuchiwać zadań
- Podsumowanie
A. Słowa kluczowe
- Obecnie używane słowa kluczowe
- Słowa kluczowe zarezerwowane do wykorzystania w przyszłości
- Surowe identyfikatory
B. Operatory i symbole
- Operatory
- Symbole niezwiązane z operatorami
C. Cechy pochodne (zapożyczone)
- Cecha Debug do uzyskiwania programistycznych danych wyjściowych
- Cechy PartialEq i Eq do porównania równości
- Cechy PartialOrd i Ord do porównywania kolejności
- Cechy Clone i Copy do duplikowania wartości
- Cecha Hash do mapowania wartości na wartość o stałym rozmiarze
- Cecha Default dla wartości domyślnych
D. Przydatne narzędzia programistyczne
- Automatyczne formatowanie za pomocą narzędzia rustfmt
- Naprawianie kodu za pomocą narzędzia rustfix
- Lintery narzędzia Clippy
- Integracja z IDE przy użyciu narzędzia rust-analyzer
E. Edycje
Kategoria: | Programowanie |
Zabezpieczenie: |
Watermark
|
ISBN: | 978-83-289-1011-9 |
Rozmiar pliku: | 4,3 MB |