📄 Page
1
(This page has no text content)
📄 Page
2
(This page has no text content)
📄 Page
3
Learn Rust Programming Safe Code, Supports Low Level and Embedded Systems Programming with a Strong Ecosystem Claus Matzinger www.bpbonline.com
📄 Page
4
Copyright © 2022 BPB Online All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor BPB Online or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book. BPB Online has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, BPB Online cannot guarantee the accuracy of this information. Group Product Manager: Marianne Conor Publishing Product Manager: Eva Brawn Senior Editor: Connell Content Development Editor: Melissa Monroe Technical Editor: Anne Stokes Copy Editor: Joe Austin Language Support Editor: Justin Baldwin Project Coordinator: Tyler Horan Proofreader: Khloe Styles Indexer: V. Krishnamurthy Production Designer: Malcolm D'Souza Marketing Coordinator: Kristen Kramer First published: July 2022 Published by BPB Online WeWork, 119 Marylebone Road London NW1 5PU UK | UAE | INDIA | SINGAPORE ISBN 978-93-55511-546 www.bpbonline.com
📄 Page
5
Dedicated to My wife and my daughter.
📄 Page
6
About the Author Claus Matzinger: In the last 10 years as a Software Engineer I have worked with many programming languages, but Rust stood out from the beginning. With its unique approaches to some of the most challenging issues when developing large-scale applications. After getting to know the language in its infancy, I spoke at and hosted several Rust Meetups (in Munich, Berlin, Linz, …), joined the official Community team, connected Microsoft’s security engineers with the Rust core team, and wrote several books and courses on Rust. Today, I am a senior engineer working on a major Rust code base in FinTech, covering everything from no_std code, to different CPU architectures, and soon WebAssembly. In the past, I have created games for improving mental health, helped build a distributed SQL database at a startup, maintained a Smalltalk application, and worked on customer’s business critical enterprise systems at Microsoft. As a quickly evolving language that is deeply technical in nature, Rust has a daunting learning curve, that I love to help new and experienced programmers overcome. For that, I also blog regularly about practical things to do with Rust at https://blog.x5ff.xyz.
📄 Page
7
Acknowledgement Creating something as fundamental as a programming language is a major undertaking by many people and it would require another book to honor each contribution. However I’d like to thank all contributors to the Rust programming language for creating such a great language - it has become more than a tool for me and many others. With this book I want to pay it forward by instilling this passion in others. In these early days of Rust, it’s not common to work with my favorite programming language on a daily basis. Thanks to the team at DEX Labs I get to tinker and work in an exciting environment that takes Rust from the lowest levels of CPUs to WebAssembly - I truly enjoy every minute of that.
📄 Page
8
Preface Rust is still a young language and throughout its “formative years” it has passed through many stages. Before Rust 1.0 was released, the language had already tried different paradigms for memory management and even types. However, leaving those initial ideas behind made the language what it is today: a really fast and safe language with a quirky memory management technique and an opinionated compiler. While it comes with a steep learning curve, the ideas have spread and other programming languages (for example Apple’s Swift) picked some parts up quickly, resulting in an overall improvement for programmers and software engineers. I am convinced that by learning Rust, you learn more about programming as well and become better for it. In many ways, the system of borrowing and ownership of memory keeps the questions “Where does this come from?” and “Where does this go?” always at the forefront of your programming mind. Even while writing JavaScript, a much more permissible language, you will become aware of where your objects are and where they should be, as well as whether or not you should create a copy. Personally, I think that alone is worth learning more Rust. To start your journey, this book provides 16 chapters in increasing difficulty. Starting with the basics, you will quickly advance towards fundamentals of the standard library, memory management, and end with highly advanced features such as Rust’s unsafe features. Each chapter comes with a challenge in the end so you can experiment with what you learned. After completing this book, you will have built your own LinkedList data structure and several other small programs from along the way. Before we start off, let’s look at what each chapter contains: Chapter 1 provides you with the basics of the Rust programming language. To set the stage appropriately, you’ll learn about byte code, compilers and compilation, simple types, and variables.
📄 Page
9
Chapter 2 goes a little deeper into program flow and controlling it. This is where you see decision making with if, as well as while and for loops introduced. Afterwards, reading short code examples in Rust won’t pose much of a challenge for you any longer. Chapter 3 covers the heart of how Rust stores data in memory. This chapter is all about creating data structures (structs), modules, and functions. For your programming journey, that means you can now store data and attach behavior (do stuff with it). Chapter 4 ventures further into the depths of Rust’s type system by exploring enumerations (enums), traits, and pattern matching. These constructs allow for more efficient decision making based on type variants and share behavior between types using traits. Chapter 5 gets to the heart of Rust’s memory management system: borrowing and ownership. The chapter details sharing data structures between functions, how to add mutability, and introduces the notion of scopes. This chapter concludes the fundamentals of the programming language, so afterwards you can solve basic and intermediate problems using Rust. Chapter 6 introduces the Rust standard library collections, which will play an important role in any Rust programming career. This includes the Vector, HashMap, HashSet, their BTree counterparts, and the Iterator trait which allows to traverse these collections. Chapter 7 covers working with input and output of various sorts, utilizing the Read and Write traits of the Rust standard library, as well as interacting with the outside world with command line arguments, Files and environment variables. Afterwards your programs can easily interact with the environment. Chapter 8 gets into how to add third party dependencies from the crates.io package repository. Additionally, the chapter covers custom build processes and custom cargo commands. Chapter 9 provides details on testing your Rust code, including unit tests, integration tests, and benchmarking. Once you know this, there is no excuse not to test your code! Chapter 10 adds documentation to your Rust repository. This means that you can generate websites from your code comments and even test the
📄 Page
10
examples. After testing, this is Rust’s way of making documenting code convenient. Chapter 11 starts the advanced part of the book by introducing macros. These code constructs allow to generate code and insert it right before the final steps of compilation. Next to using macros, you’ll learn how to create the different kinds supported in Rust as well. Chapter 12 dives deep into heap memory allocation and the types Rust provides for managing it. Together with borrowing and ownership concepts, this chapter explores reference counters, boxes, memory layouts, and the interior mutability pattern. Chapter 13 is all about concurrency using threads, locks, and synchronization. Thanks to borrowing and ownership principles, this is significantly less error-prone than in other languages. Chapter 14 expands on concurrency by explaining async, short for asynchronous programming. The chapter includes using the provided syntax elements async and await and how to use Futures to schedule tasks on an I/O loop. Chapter 15 introduces the topic of generics. Generics are a way to provide implementations on functions without relying on specific types, instead using traits. This is complemented by a deeper dive on lifetimes, since those may differ between the generic types. Chapter 16 concludes the book with an overview over unsafe and the foreign function interface (FFI). These language constructs allow you to integrate with other programs, the operating system, or other programming languages by linking libraries to Rust or creating linkable libraries from Rust. You’ll also learn about the dark arts of writing unsafe code that the compiler is less strict about…
📄 Page
11
Coloured Images Please follow the link to download the Coloured Images of the book: https://rebrand.ly/8r7c0wi We have code bundles from our rich catalogue of books and videos available at https://github.com/bpbpublications. Check them out! Errata We take immense pride in our work at BPB Publications and follow best practices to ensure the accuracy of our content to provide with an indulging reading experience to our subscribers. Our readers are our mirrors, and we use their inputs to reflect and improve upon human errors, if any, that may have occurred during the publishing processes involved. To let us maintain the quality and help us reach out to any readers who might be having difficulties due to any unforeseen errors, please write to us at : errata@bpbonline.com Your support, suggestions and feedbacks are highly appreciated by the BPB Publications’ Family. Did you know that BPB offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.bpbonline.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at: business@bpbonline.com for more details. At www.bpbonline.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive
📄 Page
12
exclusive discounts and offers on BPB books and eBooks.
📄 Page
13
Piracy If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at business@bpbonline.com with a link to the material. If you are interested in becoming an author If there is a topic that you have expertise in, and you are interested in either writing or contributing to a book, please visit www.bpbonline.com. We have worked with thousands of developers and tech professionals, just like you, to help them share their insights with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea. Reviews Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions. We at BPB can understand what you think about our products, and our authors can see your feedback on their book. Thank you! For more information about BPB, please visit www.bpbonline.com.
📄 Page
14
Table of Contents 1. Building the Basics Structure Objectives Compiling Rust code What is compilation Memory management and dynamic versus static typing Executing the code Programming in Rust Managing memory in Rust Writing Rust code Working with variable types Being literal Conclusion Challenge 2. Controlling the Program Flow Structure Objectives Making decisions with if Using conditions What if condition fails Using If/Else expressions Repetitions and repetitions with loop Continuing and breaking with values Enumerating with for Breaking on conditions with while Conclusion Challenge 3. Organizing for Reuse Structure Objectives
📄 Page
15
Encapsulating behavior with functions Parameterizing functions Encapsulating data with structs Getting a deeper look Exporting and importing with modules Aliasing types and exporting imports Conclusion Challenge 4. Interfacing with Code and Errors Structure Objectives Using traits for fun and pleasure Implementing traits Using traits in functions Creating variations with enums Handling errors with enums Matching patterns to extract data Conclusion Challenge Further reading 5. Borrowing Ownership with Scopes Structure Objectives Taking ownership of memory Working with both kinds of memory Borrowing memory Working in scopes Controlling mutability Introducing clones Conclusion Challenge 6. Working with Collections Structure Objectives
📄 Page
16
Using sequential collections: slices and Vec<T> Operating the Vec<T> Borrowing the Vec<T>: slices Deriving keys from values with sets and maps Sorting keys: trees and hashes Using sets and maps Iterating over any collection Chaining iterators together Collecting the results Conclusion Challenge Further reading 7. Reading Input and Writing Output Structure Objectives Reading from and writing to I/O streams Console, networking, and file systems Using formatted print Configuration options for programs Using command-line arguments Using environment variables Conclusion Challenge 8. Using Crates with Cargo Structure Objectives Creating crates with cargo Writing the build manifest Adding third-party crates Going deeper into cargo Customizing the build Using workspaces for large projects Conclusion Challenge Further reading
📄 Page
17
9. Testing What you Build Structure Objectives Testing Rust code Testing units Testing integration Benchmarking Rust code Conclusion Challenge 10. Documenting What You Build Structure Objectives Documenting Rust code Using sections, links, and others Writing documentation tests Publishing your documentation Conclusion Challenge 11. Generating Code with Macros Structure Objectives Declarative macros Using arguments with names and designators Adding complexity to arguments Exporting macros Procedural macros Writing function-like macros Deriving stuff with macros Using attributes to extend code Conclusion Challenge 12. Using Heap Memory Effectively Structure Objectives
📄 Page
18
Putting things in boxes Boxing data Boxing behavior Counting references Counting references with multi-threading Creating mutability as required Using locks for global mutability Conclusion Challenge Further reading 13. Running Concurrent Code Structure Objectives Threading with Rust Using Send and Sync Using alternatives Bridging threads with channels Conclusion Challenge 14. Writing Async Code Structure Objectives Scheduling tasks in a loop Polling futures Using futures-rs Using async-std Working asynchronously Running blocking code Conclusion Challenge 15. Working with Generics Structure Objectives Using Generics
📄 Page
19
Parameterizing functions Parameterizing structs, traits, and enums Going deeper Using const Generics Working with lifetimes Conclusion Challenge 16. Calling Unsafe and Foreign Functions Structure Objectives Working with unsafe Sharing native Rust code Importing a shared library Binding Rust code Exporting as shared library Conclusion Further reading Index
📄 Page
20
L CHAPTER 1 Building the Basics earning Rust is a daunting task for many. Although there is a wealth of free information available, this information is not always well structured and can be overwhelming with details and other sidetracks that are not always important. What is important, however, is to enjoy writing code and having fun with the outcome—and that is what the Rust programming language can provide. Before we can dive into full-on application building, component architecture, or even just writing sorting algorithms, we should discuss the basics. In this chapter, we are exploring the foundations that make Rust what it is a compiled, statically typed systems programming language. If none of those words means anything to you, then this chapter is for you. Rust is among the most complex of languages with a steep learning curve and a compiler that can feel infuriatingly assumptive—this is normal and to be expected. These experiences become much more reasonable once you understand the basics of the programming language and what it is all about: knowing types and when to dispose of their instances. If this chapter is your first adventure into programming, this chapter provides a few aspects of computer science that go much deeper than a single chapter of a book ever could. We encourage you to find more information on any of the topics that interest you here or simply play with the code samples and try out your own ideas. Think of this as the first step in your Rust journey (or programming as a whole), and as with any craft, and you will get better if you try things out—no matter how crazy, obvious, or ludicrous the thought. You are learning, after all. Before we discuss the intricate details of the borrow checker, we should start at the beginning: what is computer code? Structure In this chapter, we will be covering the following topics: