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

Tytuł oryginału: Programming Rust: Fast, Safe Systems Development
Tłumaczenie: Adam Bochenek, Krzysztof Sawka
ISBN: 978-83-283-5740-2
stron: 576, Format: 168x237, okładka: miękka
Data wydania: 2019-11-05
Księgarnia: Helion
Cena książki: 99,00 zł
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!
Osoby które kupowały "Programowanie w języku Rust. Wydajność i bezpieczeństwo", wybierały także:
- F# 4.0 dla zaawansowanych. Wydanie IV 96,45 zł, (29,90 zł -69%)
 - Systemy reaktywne. Wzorce projektowe i ich stosowanie 65,31 zł, (20,90 zł -68%)
 - GameMaker. Kurs video. Kompleksowy przewodnik tworzenia gier platformowych 154,58 zł, (55,65 zł -64%)
 - Poradnik design thinking - czyli jak wykorzystać myślenie projektowe w biznesie 39,21 zł, (14,90 zł -62%)
 - Flutter. Kurs video. Przewodnik dla 149,00 zł, (59,60 zł -60%)
 
Spis treści
Programowanie w języku Rust. Wydajność i bezpieczeństwo -- spis treści
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  - HashMap
i BTreeMap 377 - Entry 380
 - Iterowanie map 381
 
 - HashSet
i 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





