Details zum E-Book

Programowanie w języku Rust. Wydajność i bezpieczeństwo

Programowanie w języku Rust. Wydajność i bezpieczeństwo

Jim Blandy, Jason Orendorff

E-book

Programowanie systemowe zwykle nie interesuje twórców aplikacji. Niemniej warunkiem jej poprawnego działania jest właśnie kod systemowy. Programowanie systemowe zapewnia między innymi działanie systemu operacyjnego, sterowników, systemu plików, kodeków, a także zarządzanie pamięcią czy obsługę sieci. Jako że dotyczy wykorzystania zasobów, każdy szczegół, każdy bajt pamięci operacyjnej i każdy cykl procesora ma znaczenie. Rust - wyjątkowe narzędzie, cenione za szybkość, współbieżność i bezpieczeństwo - sprawi, że tworzenie kodu systemowego będzie łatwiejsze. Jednak tym, którzy dotychczas używali C#, Javy czy Pythona, język ten może się wydawać dość trudny do zrozumienia.

Ta książka jest znakomitym wprowadzeniem do języka Rust, pozwala też rozeznać się w zasadach programowania systemowego. Pokazuje, w jaki sposób zapewnić w kodzie bezpieczeństwo pamięci i wątków oraz sprawić, aby program był wykonywany szybko i bez błędów. Poszczególne zagadnienia zostały przedstawione jasno i przystępnie, a prezentowane koncepcje - zilustrowane licznymi przykładami kodu. Nie zabrakło również wskazówek ułatwiających bezproblemowe tworzenie wydajnego i bezpiecznego kodu. Książka jest przeznaczona przede wszystkim dla programistów systemowych, jednak przyda się także twórcom aplikacji, którym pozwoli zrozumieć zasady rządzące językiem Rust, a w efekcie tworzyć lepszy i łatwiejszy w utrzymaniu kod.

W tej książce między innymi:

  • solidne wprowadzenie do języka Rust
  • podstawowe typy danych, własności i referencje
  • obsługa błędów w języku Rust
  • obsługa wejścia-wyjścia, makra i współbieżność
  • obsługa niebezpiecznego kodu

Rust. Programowanie systemowe. Najlepiej zacząć od podstaw!


Wstęp 15

1. Dlaczego Rust? 19

  • Bezpieczeństwo typów 21

2. Pierwsze spotkanie z Rustem 25

  • Pobranie i instalacja Rusta 25
  • Prosta funkcja 28
  • Pisanie i uruchamianie testów 29
  • Obsługa argumentów wiersza poleceń 30
  • Prosty serwer web 34
  • Programowanie współbieżne 41
    • Czym jest zbiór Mandelbrota? 42
    • Parsowanie argumentów wiersza poleceń 46
    • Odwzorowanie pikseli na liczby zespolone 48
    • Rysowanie zbioru 50
    • Zapis obrazu do pliku 51
    • Program Mandelbrota działający współbieżnie 53
    • Uruchomienie programu 57
    • Przezroczyste bezpieczeństwo 57

3. Typy proste 59

  • Typy maszynowe 62
    • Typy całkowite 62
    • Typy zmiennoprzecinkowe 65
    • Typ logiczny 67
    • Typ znakowy 67
  • Krotki 69
  • Typy wskaźnikowe 71
    • Referencje 71
    • Pudełka 72
    • Wskaźniki niechronione 72
  • Tablice, wektory i podzbiory 72
    • Tablice 73
    • Wektory 74
    • Dodawanie pojedynczych elementów do wektora 77
    • Podzbiory 77
  • Typ String 79
    • Literały łańcuchowe 79
    • Łańcuchy bajtów 80
    • Łańcuchy znaków w pamięci 80
    • Typ String 82
    • Podstawowe cechy typu String 83
    • Inne typy znakowe 83
  • Co dalej? 84

4. Reguła własności 85

  • Reguła własności 87
  • Przeniesienie własności 91
    • Więcej operacji związanych z przeniesieniem własności 96
    • Przeniesienie własności a przepływ sterowania 97
    • Przeniesienie własności a struktury indeksowane 98
  • Typy kopiowalne 100
  • Rc i Arc: własność współdzielona 103

5. Referencje 107

  • Referencje jako wartości 111
    • Referencje Rusta kontra referencje C++ 111
    • Referencje a operacja przypisania 112
    • Referencje do referencji 112
    • Porównywanie referencji 113
    • Referencje nigdy nie są puste 114
    • Referencje do wyrażeń 114
    • Referencje do podzbiorów i zestawów metod 115
  • Bezpieczeństwo referencji 115
    • Referencja do zmiennej lokalnej 115
    • Parametry w postaci referencji 118
    • Referencje jako argumenty 120
    • Referencja jako wartość zwracana 121
    • Struktura zawierająca referencje 122
    • Odrębny cykl życia 124
    • Pomijanie parametrów cyklu życia 125
  • Referencje współdzielone kontra mutowalne 127
  • Walka ze sztormem na morzu obiektów 134

6. Wyrażenia 137

  • Język wyrażeń 137
  • Bloki kodu i średniki 138
  • Deklaracje 140
  • if i match 141
    • if let 143
  • Pętle 144
  • Wyrażenie return 146
  • Analiza przepływu sterowania 146
  • Wywołania funkcji i metod 148
  • Pola i elementy 149
  • Operatory referencji 150
  • Operatory arytmetyczne, bitowe, porównania i logiczne 150
  • Przypisanie 151
  • Rzutowanie typów 152
  • Domknięcia 153
  • Priorytety operatorów 153
  • Co dalej? 156

7. Obsługa błędów 157

  • Błąd panic 157
    • Odwinięcie stosu 158
    • Przerywanie procesu 159
  • Typ Result 160
    • Przechwytywanie błędów 160
    • Alias typu Result 161
    • Wyświetlanie informacji o błędach 162
    • Propagacja błędów 163
    • Jednoczesna obsługa błędów różnych typów 164
    • Błędy, które nie powinny się zdarzyć 166
    • Ignorowanie błędów 167
    • Obsługa błędów w funkcji main() 167
    • Definiowanie własnego typu błędu 168
    • Co daje nam typ Result? 169

8. Paczki i moduły 171

  • Paczki 171
    • Profile budowania 174
  • Moduły 174
    • Umieszczanie modułów w oddzielnych plikach 175
    • Ścieżki i importy 177
    • Standardowe preludium 179
    • Podstawowe składniki modułów 179
  • Zmiana programu w bibliotekę 181
  • Katalog src/bin 183
  • Atrybuty 184
  • Testy i dokumentacja 186
    • Testy integracyjne 188
    • Dokumentacja 189
    • Doc-testy 191
  • Definiowanie zależności 193
    • Wersje 194
    • Cargo.lock 195
  • Publikowanie paczek na stronie crates.io 196
  • Obszary robocze 198
  • Więcej fajnych rzeczy 199

9. Struktury 201

  • Struktury z polami nazywanymi 201
  • Struktury z polami numerowanymi 204
  • Struktury puste 204
  • Reprezentacja struktur w pamięci 205
  • Definiowanie metod w bloku impl 206
  • Struktury generyczne 209
  • Struktury z parametrem cyklu życia 210
  • Dziedziczenie standardowych zestawów metod 211
  • Zmienność wewnętrzna 212

10. Typy wyliczeniowe i wzorce 217

  • Typy wyliczeniowe 218
    • Typy wyliczeniowe zawierające dane 220
    • Typ wyliczeniowy w pamięci 221
    • Większe struktury danych stosujące typy wyliczeniowe 222
    • Generyczne typy wyliczeniowe 223
  • Wzorce 226
    • Literały, zmienne i symbole wieloznaczne 228
    • Wzorce w postaci krotki lub struktury 230
    • Wzorce z referencjami 231
    • Dopasowanie do wielu wartości 233
    • Warunki dodatkowe 234
    • Wzorce @ 235
    • Gdzie używamy wzorców 235
    • Wypełnianie drzewa binarnego 236
  • Podsumowanie 238

11. Zestawy metod (interfejsy) i typy generyczne 239

  • Stosowanie zestawów metod 241
    • Obiekt implementujący zestaw metod 242
    • Struktura obiektu implementującego 243
    • Funkcje generyczne 244
    • Na co się zdecydować? 247
  • Definiowanie i implementacja zestawów metod 249
    • Metody domyślne 250
    • Implementacja zestawów metod dla istniejących już typów 251
    • Zestaw metod a słowo kluczowe Self 252
    • Rozszerzanie zestawu metod (dziedziczenie) 254
    • Metody statyczne 254
  • W pełni kwalifikowana nazwa metody 255
  • Zestawy metod definiujące relacje między typami 257
    • Typy powiązane 257
    • Generyczny zestaw metod (czyli jak działa przeciążanie operatorów) 260
    • Zaprzyjaźnione zestawy metod (czyli jak działa generator liczb pseudolosowych) 261
  • Inżynieria wsteczna ograniczeń 263
  • Wnioski 266

12. Przeciążanie operatorów 267

  • Operatory arytmetyczne i bitowe 268
    • Operatory jednoargumentowe 270
    • Operatory dwuargumentowe 271
    • Operatory przypisania złożonego 272
  • Test równości 273
  • Porównania szeregujące 276
  • Interfejsy Index i IndexMut 278
  • Inne operatory 281

13. Interfejsy narzędziowe 283

  • Drop 284
  • Sized 287
  • Clone 289
  • Copy 290
  • Deref i DerefMut 291
  • Default 294
  • AsRef i AsMut 296
  • Borrow i BorrowMut 297
  • From i Into 299
  • ToOwned 301
  • Borrow i ToOwned w działaniu 302

14. Domknięcia 305

  • Przechwytywanie zmiennych 306
    • Domknięcia, które pożyczają wartość 307
    • Domknięcia, które przejmują własność 308
  • Typy funkcji i domknięć 309
  • Domknięcia a wydajność 311
  • Domknięcia a bezpieczeństwo 313
    • Domknięcia, które zabijają 313
    • FnOnce 314
    • FnMut 315
  • Funkcje zwrotne 317
  • Skuteczne korzystanie z domknięć 320

15. Iteratory 323

  • Iterator i IntoIterator 324
  • Tworzenie iteratorów 326
    • Metody iter i iter_mut 326
    • Implementacje interfejsu IntoIterator 326
    • Metoda drain 328
    • Inne źródła iteratorów 329
  • Adaptery 330
    • map i filter 330
    • filter_map i flat_map 333
    • scan 335
    • take i take_while 335
    • skip i skip_while 336
    • peekable 337
    • fuse 338
    • Iteratory obustronne i rev 339
    • inspect 340
    • chain 341
    • enumerate 341
    • zip 342
    • by_ref 342
    • cloned 344
    • cycle 344
  • Konsumowanie iteratorów 345
    • Proste agregaty: count, sum i product 345
    • max i min 345
    • max_by i min_by 346
    • max_by_key i min_by_key 346
    • Porównywanie sekwencji elementów 347
    • any i all 348
    • position, rposition oraz ExactSizeIterator 348
    • fold 349
    • nth 349
    • last 350
    • find 350
    • Tworzenie kolekcji: collect i FromIterator 350
    • Zestaw metod Extend 352
    • partition 353
  • Implementacja własnych iteratorów 354

16. Kolekcje 359

  • Przegląd kolekcji 360
  • Vec 361
    • Dostęp do elementów 362
    • Iteracja 363
    • Zwiększanie i zmniejszanie wielkości wektora 364
    • Łączenie 367
    • Podział 367
    • Zamiana 369
    • Sortowanie i wyszukiwanie 370
    • Porównywanie podzbiorów 371
    • Elementy losowe 372
    • Reguły zapobiegające konfliktom w czasie iteracji 372
  • VecDeque 373
  • LinkedList 375
  • BinaryHeap 376
  • HashMapi BTreeMap 377
    • Entry 380
    • Iterowanie map 381
  • HashSeti BTreeSet 382
    • Iteracja zbioru 383
    • Kiedy równe wartości są różne 383
    • Operacje dotyczące całego zbioru 383
  • Haszowanie 385
    • Niestandardowe algorytmy haszujące 386
  • Kolekcje standardowe i co dalej? 387

17. Tekst i łańcuchy znaków 389

  • Podstawy Unicode 389
    • ASCII, Latin-1 i Unicode 390
    • UTF-8 390
    • Kierunek tekstu 392
  • Znaki (typ char) 392
    • Klasyfikacja znaków 392
    • Obsługa cyfr 393
    • Zmiana wielkości liter 394
    • Konwersja znaku do i z liczby całkowitej 394
  • Typy String i str 395
    • Tworzenie łańcuchów znaków 396
    • Prosta inspekcja 396
    • Dołączanie i wstawianie tekstu 397
    • Usuwanie tekstu 398
    • Konwencje nazewnicze dotyczące wyszukiwania i iterowania 399
    • Wyszukiwanie tekstu i wzorce 399
    • Wyszukiwanie i zamiana 400
    • Iterowanie tekstu 401
    • Obcinanie 403
    • Zmiana wielkości liter w łańcuchach 403
    • Konwersja tekstu do wartości innego typu 404
    • Konwersja wartości innego typu do tekstu 404
    • Tworzenie referencji innego typu 405
    • Tekst jako UTF-8 406
    • Tworzenie tekstu na podstawie danych UTF-8 406
    • Alokacja warunkowa 407
    • Łańcuchy znaków jako kolekcje generyczne 409
  • Formatowanie wartości 410
    • Formatowanie tekstu 411
    • Formatowanie liczb 412
    • Formatowanie innych typów 414
    • Formatowanie wartości z myślą o debugowaniu 415
    • Formatowanie i debugowanie wskaźników 416
    • Wiązanie argumentów za pomocą indeksu i nazwy 416
    • Dynamiczne definiowanie długości i precyzji 417
    • Formatowanie własnych typów 417
    • Użycie języka formatowania we własnym kodzie 419
  • Wyrażenia regularne 421
    • Podstawowe użycie wyrażeń regularnych 421
    • Wyrażenia regularne w trybie leniwym 422
  • Normalizacja 423
    • Rodzaje normalizacji 424
    • Biblioteka unicode-normalization 425

18. Operacje wejścia/wyjścia 427

  • Obiekty typu reader i writer 428
    • Obiekty typu reader 429
    • Buforowany obiekt typu reader 431
    • Przeglądanie tekstu 432
    • Pobieranie tekstu 434
    • Obiekty typu writer 435
    • Pliki 436
    • Wyszukiwanie 437
    • Inne rodzaje obiektów reader i writer 437
    • Dane binarne, kompresja i serializacja 439
  • Pliki i katalogi 440
    • OsStr i Path 440
    • Metody typów Path i PathBuf 442
    • Funkcje dostępu do systemu plików 443
    • Odczyt zawartości katalogu 444
    • Funkcje bezpośrednio związane z platformą 446
  • Obsługa sieci 447

19. Programowanie współbieżne 451

  • Podział i łączenie wątków 453
    • spawn i join 454
    • Obsługa błędów w różnych wątkach 456
    • Współdzielenie niemutowalnych danych przez różne wątki 457
    • Rayon 459
    • Zbiór Mandelbrota raz jeszcze 461
  • Kanały 463
    • Wysyłanie wartości 464
    • Odczyt wartości 467
    • Uruchomienie potoku 468
    • Cechy kanałów i ich wydajność 470
    • Bezpieczeństwo wątków: Send i Sync 472
    • Współpraca iteratora i kanału 474
    • Potoki i co dalej? 475
  • Stan współdzielony mutowalny 476
    • Czym jest muteks? 476
    • Mutex 478
    • mut i Mutex 480
    • Dlaczego Mutex to nie zawsze dobry pomysł? 480
    • Zakleszczenie (deadlock) 481
    • Zatruty muteks 482
    • Kanały z wieloma nadawcami stosujące muteksy 482
    • Blokady odczytu/zapisu (RwLock) 483
    • Zmienne warunkowe (Condvar) 485
    • Typy atomowe 485
    • Zmienne globalne 487
  • Rust i pisanie programów wielowątkowych 489

20. Makra 491

  • Podstawy 492
    • Rozwijanie makra 493
    • Niezamierzone skutki 495
    • Powtórzenia 496
  • Makra wbudowane 498
  • Debugowanie makr 499
  • Makro json! 500
    • Typy składników 501
    • Makra a rekurencja 504
    • Makra i zestawy metod 505
    • Zakres i higiena 507
    • Import i eksport makr 509
  • Unikanie błędów składniowych w procesie dopasowywania 511
  • macro_rules! i co dalej? 512

21. Kod niebezpieczny 513

  • Dlaczego niebezpieczny? 514
  • Bloki unsafe 515
    • Przykład: skuteczny typ łańcucha znaków ASCII 516
  • Funkcje unsafe 518
  • Kod niebezpieczny czy funkcja niebezpieczna? 520
  • Niezdefiniowane zachowanie 521
  • Zestawy metod unsafe 523
  • Wskaźniki niechronione 525
    • Bezpieczne tworzenie dereferencji wskaźników niechronionych 528
    • Przykład: RefWithFlag 529
    • Wskaźniki dopuszczające wartość pustą 531
    • Rozmiary i rozmieszczanie typów 531
    • Operacje arytmetyczne na wskaźnikach 532
    • Wchodzenie do pamięci i wychodzenie z pamięci 534
    • Przykład: GapBuffer 537
    • Bezpieczeństwo błędów paniki w kodzie niebezpiecznym 543
  • Funkcje obce: wywoływanie kodu C i C++ w środowisku Rusta 544
    • Wyszukiwanie wspólnych reprezentacji danych 544
    • Deklarowanie obcych funkcji i zmiennych 547
    • Korzystanie z funkcji i bibliotek 549
    • Interfejs niechroniony dla biblioteki libgit2 552
    • Interfejs bezpieczny dla biblioteki libgit2 558
  • Podsumowanie 568

Skorowidz 569

  • Titel: Programowanie w języku Rust. Wydajność i bezpieczeństwo
  • Autor: Jim Blandy, Jason Orendorff
  • Originaler Titel: Programming Rust: Fast, Safe Systems Development
  • Übersetzung: Adam Bochenek, Krzysztof Sawka
  • ISBN: 978-83-283-5741-9, 9788328357419
  • Veröffentlichungsdatum: 2019-11-05
  • Format: E-book
  • Artikelkennung: prrust
  • Verleger: Helion