41,99 €
Start building fast and robust applications with the power of Rust by your side
The book is for absolute beginners to Rust, who want to build high performance, concurrent applications for their projects. It is suitable for developers who have a basic knowledge of programming and developers who are using the C#/C++ language to write their applications. No knowledge of Rust is expected.
Rust is a highly concurrent and high performance language that focuses on safety and speed, memory management, and writing clean code. It also guarantees thread safety, and its aim is to improve the performance of existing applications. Its potential is shown by the fact that it has been backed by Mozilla to solve the critical problem of concurrency.
Learning Rust will teach you to build concurrent, fast, and robust applications. From learning the basic syntax to writing complex functions, this book will is your one stop guide to get up to speed with the fundamentals of Rust programming. We will cover the essentials of the language, including variables, procedures, output, compiling, installing, and memory handling.
You will learn how to write object-oriented code, work with generics, conduct pattern matching, and build macros. You will get to know how to communicate with users and other services, as well as getting to grips with generics, scoping, and more advanced conditions. You will also discover how to extend the compilation unit in Rust.
By the end of this book, you will be able to create a complex application in Rust to move forward with.
This comprehensive book will focus on the Rust syntax, functions, data types, and conducting pattern matching for programmers. It is divided into three parts and each part of the book has an objective to enable the readers to create their own applications at an appropriate level, ultimately towards creating complex applications.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 302
Veröffentlichungsjahr: 2017
Copyright © 2017 Packt Publishing
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 authors, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: November 2017
Production reference: 1221117
ISBN 978-1-78588-430-6
www.packtpub.com
Authors
Paul Johnson
Vesa Kaihlavirta
Copy Editor
Safis Editing
Reviewer
Ivo Balbaert
Project Coordinator
Ulhas Kambali
Commissioning Editor
Kunal Parikh
Proofreader
Safis Editing
Acquisition Editor
Denim Pinto
Indexer
Rekha Nair
Content Development Editor
Nikhil Borkar
Graphics
Kirk D'Penha
Technical Editor
Madhunikita Sunil Chindarkar
Production Coordinator
Arvindkumar Gupta
Paul Johnson has been writing software since the early 1980s on machines ranging from the ZX81 and servers to his trusty Mac, and has used more languages than he can remember. He is a qualified scuba diver and college lecturer. Paul lives with his wife, kids, and pets, and listens to an inordinate amount of rock and metal on Primordial Radio. This is his third book for Packt.
Vesa Kaihlavirta has been programming since he was 5, beginning with C64 Basic. His main professional goal in life is to increase awareness about programming languages and software quality in all industries that use software. He's an Arch Linux Developer Fellow and has been working in the telecom and financial industry for over a decade. Vesa lives in Central Finland, in Jyväskylä. Vesa worked on the final editing phase of Learning Rust.
Ivo Balbaert is currently a lecturer of (web) programming and databases at CVO Antwerpen (www.cvoantwerpen.be), a community college in Belgium. He received a PhD in applied physics from the University of Antwerp in 1986. He worked for 20 years in the software industry as a developer and consultant at several companies, and for 10 years as a project manager at the Antwerp University Hospital. From 2000 onwards, he switched to partly teaching and partly developing software (KHM Mechelen, CVO Antwerpen).
In 2012, he authored a book on the Go programming language, The Way To Go, IUniverse. In 2013, in collaboration with Dzenan Ridzanovic, he wrote Learning Dart and Dart Cookbook, followed by Getting Started with Julia Programming Language and Rust Essentials, all published by Packt.
For support files and downloads related to your book, please visit www.PacktPub.com. Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details. At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
https://www.packtpub.com/mapt
Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review on this book's Amazon page at https://www.amazon.com/dp/1785884301.
If you'd like to join our team of regular reviewers, you can email us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!
BIRMINGHAM - MUMBAI
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Errata
Piracy
Questions
Introducing and Installing Rust
Installing Rust
Installing rustup on Linux
gcc prerequisites
Testing your installation
Integrated Development Environment
Your first Rust project
Structure of a Rust project
Automating things
Creating a binary package using Cargo
Using Cargo to build and run an application
Cleaning your source tree with Cargo
Creating documentation using Cargo
rustdoc versus Cargo
Using Cargo to help with your unit testing
Assert yourself!
Is there anything Cargo can't do?
Summary
Variables
Variable mutability
Creating a variable
How can we tell the compiler that we want x to be an int?
Defining other variable types
Float
Signed and unsigned integers
Const and static
Defining the variable value before use
Strings
How Rust uses memory
Back to Strings
String slices
What's with the warnings?
Using the format! macro
Building a string
Code review
Casting
String methods
Generics and arrays
Arrays
Array performance
Vectors
Creating a vector with an initial size
Creating a vector via an iterator
Adding and removing from the vector
Manipulating an array or vector via slices
Passing values around
Passing by value
Passing by reference
The reference type
A practical example
Summary
Input and Output
Functions and methods in Rust
The difference between println! and println
Introduction to the standard library
The libraries
Controlling the output formatting
Positioning the output
Named parameters
Specifying the argument types
Formatting traits
Formatting parameters
Getting information in
Command-line arguments
Handling files
Reading from a file
Loading a file
Writing a file
The use of expect
XML and Rust
Reading a file
Writing a file
Summary
Conditions, Recursion, and Loops
Loops
The for loop
Using enumerate
The _ parameter
The simple loop
The while condition
Prematurely terminating a loop
Using loop labels
Recursive functions
What is the difference between having and not having a semicolon?
Summary
Remember, Remember
Let's start at the beginning
The stack frame
What is meant by the stack?
Let's consider the heap
Deallocation
What about functions with arguments?
Static memory allocation
Garbage collecting time and ownership
An owned pointer example
Comparison to C
Let's revisit some old code
Let's not race ahead!
Stop the race...
Summary
Creating Your Own Rust Applications
Project 1 - let's start with some math
Requirements
Supplied data
Application output
Project 2 - some text manipulation
Requirements
Code notes
Project 3 – area and volume
Shape types
Volume or area
User-defined shape
Formulae for calculations
Testing criteria
Auto-documentation
Using regular expressions (regex)
Input and output
Project 4 – memory
Bitwise rotation
Rotation caveat
Output
Summary
Matching and Structures
Structs 101
Variables, variables everywhere
The structure of a struct
Smaller is better
Accessing a struct
Defining the child structures
Multi-file version
Private versus public fields
Structs 102
Tuples
Using a tuple to define a variable
Tuple indexing
Destructuring with let
Tuple structs – the hybrid of two
The single element tuple struct
Back to the unit-like struct
Enumerations
Accessing enumeration members
The two questions you should be asking
Patterns and matching
Matching
Let's really make the function simple
Using match with an enum
Ignoring a parameter with match
Fall through patterns
Ranges
Creating a binding within a match pattern
Let's add an if into the mix
Using match with a compound type
And back to if let
Summary
The Rust Application Lifetime
What are they?
Ownership
Borrowing
Lifetime
Ownership in Rust
Abstractions
Ownership – from the beginning
Variable binding
Stack and heap variables
Why is this important?
The Copy trait
Borrowing in Rust
Borrow immutability
Mutable borrows
The Rust borrowing rules
Fixing the problem
Think about the scope
It's all for your own good
The lifetime
The mythical bank account
The lifetime variable - '
Lifetime of other types
Lifetime within an struct
Multiple lifetimes
Always consider the scope
'struct
Input and output lifetimes
Input only
Output only
Input and output
Summary
Introducing Generics, Impl, and Traits
Generics 101
Understanding the error
A generic problem
The unsafe directive
The whole #!
Traits and Impl
Impl
The impl lifetime
And back to traits we go...
A simple crate example
Traits and generics
Defining the impl for specific types
Using where
Making it work
Something you may have noticed
Generics - a small aside
So what does happen?
Back to the where version
Try to compile
Trait bounds
Can we reduce the amount of code further?
Can the default method be overridden?
Rounding off traits
Inheritance
Deriving
Trait objects
Let's create a sample test setup
Let's see dynamic dispatch
Keeping your object safe
Summary
Creating Your Own Crate
What exactly is a crate?
Looking at modules
I can see a problem with this analogy
Back to our math library
Using a useful name
Let's create!
Creating top-level modules
The multifile module
What about submodules?
The mod.rs file
Let's add some code
Beware of double name scopes
Adding unit tests to the library
Making something public
Let's give our crate a quick run out
External dependencies
Changing the scope
Altering the crate name
Optimizing your use statements
The use-everything approach
The you-decide approach
The use-me approach
The use-me-but-call-me-something-else approach
The use-glob approach
The use-glob-self approach
Summary
Concurrency in Rust
A bit of a story
What was that all about?
Send
Sync
When is an immutable variable not an immutable variable?
And it's obviously mutable, it has mut in the definition
Interior mutability
Back to sync
A beginner's guide to threading in Rust
An easy approach to thinking about how threads work.
Joining threads
Closures
Closures aren't all they first appear to be
Closures as function arguments
Closures with explicit lifetimes – a special case
Returning a closure
What is the move parameter?
Back to threading
Ownership has its advantages
The reference counter
Problem solved – use Mutex
Why do we put the thread to sleep?
Thread synchronization
Thread panics
Summary
Now It's Your Turn!
Task 1 – cleaning the code (part 1)
The problems with each option
The String option
The struct option
The task
Task 2 – cleaning the code (part 2)
The task
Task 3 – extending the crate (part 1)
The task
Task 4 – extending the crate (part 2)
Summary
The Standard Library
Chapter format
What is the standard library?
The standard modules (overview)
Primitive types (overview)
Macros (overview)
Prelude
The standard modules
std::Any
std::ascii
std::borrow
std::boxed
std::cell
std::char
std::clone
std::cmp
std::collections
std::convert
std::default
std:env
std:error
std::f32
std::f64
std:ffi
std::fmt
std::fs
std::hash
std::i8
std::i16
std::i32
std::i64
std::io
std::isize
std::iter
std::marker
std::mem
std:net
std::num
std::os
std::panic
std::path
std::process
std::ptr
std::slice
std::str
std::string
std::sync
std::thread
std::time
std::u8
std::u16
std::u32
std::u64
std::usize
std::vec
Summary
Foreign Function Interfaces
Introducing our simple library
The three-step program
Including the dependency
Creating the code
What's the [link(name="")] for?
What's the big deal? That was simple enough!
Let's extend things a bit
What happens if the types don't match?
Can we make things safer?
Wrappers
A practical example
Accessing global variables
Cleaning up after yourself
Drop it!
Monitoring an external process within an FFI
Targeting synchronous callbacks
Targeting a Rust object
Calling Rust from another language
Dealing with the unknown
C structs
Summary
Rust is a new programming language. It offers performance and safety that is equivalent to, or even surpasses, modern C++ while being a modern language with a relatively low barrier to entry. Rust's momentum, combined with its active and friendly community, promise a great future for the language.
While modern and fluent, Rust is not a particularly easy language. The memory management system keeps track of the life of every entity that is used in your program and is designed in such a way that this tracking can typically happen entirely at compile time. The Rust programmer's burden is to help the compiler when it cannot decide for itself what should happen. Since modern programming is possible without ever facing such responsibilities, a modern programmer may not immediately feel comfortable with Rust.
However, like all expertise and skill, the more difficult it is to attain, the more valuable it is, and this book is here to help you. This book covers the basics of Rust, enabling you to gain enough skills to start programming with it.
Chapter 1, Introducing and Installing Rust, deals with installing the Rust toolset and using the basic tools.
Chapter 2, Variables, focuses on using different kinds of variables.
Chapter 3, Input and Output, covers the basic I/O.
Chapter 4, Conditions, Recursion, and Loops, goes through the different loops and iterative methods of Rust.
Chapter 5, Remember, Remember, covers Rust's memory handling system.
Chapter 6, Creating Your Own Rust Applications, gives you the task of building a complete Rust application.
Chapter 7, Matching and Structures, teaches you compound data types and how to destructure them.
Chapter 8, The Rust Application Lifetime, covers Rust's unique ownership, borrowing, and lifetime system, which enables resource safety without garbage collection.
Chapter 9, Introducing Generics, Impl, and Traits, goes through Rust's generic types.
Chapter 10, Creating Your Own Crate, instructs you how to build your own contained packages of Rust code.
Chapter 11, Concurrency in Rust, looks at concurrency and parallelism techniques.
Chapter 12, Now It's Your Turn!, gives you another set of tasks to complete.
Chapter 13, The Standard Library, covers Rust's standard library.
Chapter 14, Foreign Function Interfaces, introduces techniques to interface Rust code with C programs.
To really dive into the content of this book, you should write out the example code and do the exercises. For that, you'll need a fairly recent computer; a gigabyte of RAM should be enough for the purposes of this book, but the more you have the faster the builds will be.
Linux is the best supported operating system here, but Rust itself is a first-class citizen on macOS and recent versions of Windows, so all the examples should adapt well there.
This book will appeal to application developers who would like to build applications with Rust. No knowledge of programming is required.
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply email [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files emailed directly to you. You can download the code files by following these steps:
Log in or register to our website using your email address and password.
Hover the mouse pointer on the
SUPPORT
tab at the top.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box.
Select the book for which you're looking to download the code files.
Choose from the drop-down menu where you purchased this book from.
Click on
Code Download
.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR / 7-Zip for Windows
Zipeg / iZip / UnRarX for Mac
7-Zip / PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Learning-Rust. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title. To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy of copyrighted material on the internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the internet, please provide us with the location address or website name immediately so that we can pursue a remedy. Please contact us at [email protected] with a link to the suspected pirated material. We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
Rust is a fairly new addition to the ever-growing number of programming languages available to developers. If you've never used Rust, but come from pretty much any procedural language (such as C or Pascal) or are used to shell scripting, then you should very quickly feel right at home when using Rust.
Getting to grips with Rust is simple enough, and in this chapter we will cover the following topics:
Installing Rust with rustup
Testing the installation
Setting up a project
Looking at the IDEs available
Automation using Cargo
As with most languages, Rust is available for a wide number of platforms. It would be impossible to go through installing the compiler on every variant of every operating system. Fortunately, there's an official method of installing Rust, and even though the details may differ slightly, the process is almost the same on all platforms. Therefore, this book will cover installing Rust using rustup on Fedora 27.
https://rustup.rs always contains up-to-date instructions on how to get going on all platforms. On Linux and macOS, it will look something like this:
On Windows, this text is replaced by a link to rustup-init.exe, which is an executable that installs and sets up rustup on Windows.
Run the suggested command that is shown at https://rustup.rs. Run this command in a Terminal. The script suggests some defaults and asks you to confirm them. This is roughly what it should look like after completing the whole script:
Note that this script attempts to set up rustup for your user by editing your .profile and .bash_profile files. If you are using a custom setup, such as another shell, you may need to add the source $HOME/.cargo/env command manually.
After finishing this script, you can verify that it worked by logging off and on from your Terminal and verifying that the tools are in your path:
To build any software that links against external libraries, you will need a C compiler and development versions of any libraries you may be linking against. To ensure that things work properly, install the compiler using the standard method for your operating system.
In Fedora, this would be done using the dnf tool:
sudo dnf install -y gcc
If you are unsure whether you have gcc installed, type the following command in a terminal window:
gcc -version
If gcc is installed, you'll see something like this:
Open a command-prompt window and type this:
rustc --version
If everything was installed correctly, you will see something like this:
To effectively code Rust, you will need at least some sort of text editor. All popular editors are properly supported, so if your favorite is Vim, Emacs, or any of the others, you will find a high-quality Rust extension there. The website https://areweideyet.com/ should give a current view of how things are.
We will cover the lightweight IDE from Microsoft, Visual Studio Code, and its most current Rust extension, called simply Rust. This IDE should work fairly well in all the different desktop environments. Installation instructions and packages for several platforms are available at Visual Studio Code's main site, https://code.visualstudio.com.
Open up
Visual Studio Code
and go to the Command Palette, either by the
View
menu or by the keyboard shortcut
Ctrl
+
Shift
+
P
(which may differ between platforms). Type in
install extension
to look for the proper command, and then select
Install Extensions
:
After selecting this, type
rust
into the next field to look for the
Rust
extension. At the time of writing, the most recent one is made by
kalitaalexey
:
You can install Rust right away by pressing
Install
; alternatively, click on the list item itself to show information about the extension first. After installing it, reload the editor. The
Rust
extension is now installed and ready to use!
Your first Rust project is not going to be particularly amazing. If anything, it's going to serve four purposes:
Showing the structure of a Rust project
Showing how to create a project by hand
Showing how to create a project using the Rust Cargo script
Compiling and executing the program
A Rust project (irrespective of the platform you are developing on) will have the following structure:
The preceding screenshot shows the structure of the simplest Rust project, and as such can be replicated using the following commands:
OS X/Linux
Windows (from the command prompt)
mkdir firstproject cd firstproject touch Cargo.toml mkdir src cd src touch main.rs
md firstproject cd firstproject md src echo $null >> Cargo.toml cd src echo $null >> main.rs
The Cargo.toml file is the Rust equivalent of a Makefile. When the .toml file is created by hand, it should be edited to contain something like this:
The structure of a Rust project can expand to include documentation as well as the build structure, as follows:
While there is nothing wrong with creating a Rust project by hand, Rust does come with a very handy utility called Cargo. Cargo can be used not only to automate the setting up of a project, but also to compile and execute Rust code. Cargo can be used to create the parts required for a library instead of an executable, and can also generate application documentation.
As with any other script, Cargo works (by default) on the current working directory. (For example, while writing this chapter, my working directory for the example code is ~/Developer/Rust/chapter0 on the Mac and Linux boxes, and J:\Developer\Rust\Chapter0 on the Windows 10 machine.)
In its simplest form, Cargo can generate the correct file structure like this:
cargo new demo_app_name -bin
The preceding command tells Cargo to create a new structure called demo_app_name, and that it is to be a binary. If you remove -bin, it creates a structure called, which is going to be a library (or more accurately, something other than a binary).
If you don't wish to use the root (say you want to create a library within your binary framework), then instead of demo_app_name, you append the structure before the name relating to your working directory.
In the small example I gave earlier, if I wanted to create a library within my binary structure, I would use the following:
cargo new app_name/mylib
That will create a structure like this:
The Cargo.toml file requires no editing (at this stage), as it contains the information we had to enter manually when we created the project by hand.
As we are all able to create directory structures, Cargo is then able to build and execute our source code.
If you look at the source code that comes with this chapter, you will find a directory called app_name. To build this package using Cargo, type the following from a Terminal (or command on Windows) window:
cd app_name
cargo build app_name
This will build the source code; finally you will be informed that the compilation has been successful:
Next, we can use Cargo to execute the binary as follows:
cargo run
If everything has worked, you will see something like the following:
As with any sort of utility, it's possible to "daisy-chain" the build and execution into one line, as follows:
cargo build; cargo run
When the Rust compiler compiles the source files, it generates something known as an object file. The object file takes the source file (which we can read and understand) and compiles this into a form that can be joined with other libraries to create a binary.
This is a good idea, as it cuts down on compilation time; if a source file has not been changed, there is no need to recompile the file, as the object file will be the same.
Sometimes, the object file becomes out of date, or code in another object file causes a panic due to conflicts. In this case, it is not uncommon to "clean" the build. This removes the object files, and the compiler then has to recompile all the source files.
Also, it should always be performed prior to creating a release build.
The standard Unix make program performs this with the clean command (make clean). Cargo performs the clean operation in a way similar to the make utility in Unix:
cargo clean
A comparison of the directories shows what happens when using the preceding Cargo command:
The entire target directory structure has simply been removed (the preceding screenshot was from a Mac, hence the dSYM and plist files. These do not exist on Linux and Windows).
As with the other operations provided by Cargo, when documentation is created, it acts as a wrapper for rustdoc. The only difference is that with rustdoc you have to specify the directory that the source file sits in. Cargo acts dumb in this case, and creates the documentation for all source files.
In its simplest form, the rustdoc command is used as follows:
cargo doc
rustdoc src/main.rs
Cargo does have the advantage of creating the doc structure within the root folder, whereas rustdoc creates the structure within the target (which is removed with cargo clean).
For a Rust developer, Cargo is an amazing utility. In addition to these common facilities, it also has other commands, which are listed in the table that follows. All commands follow this form:
cargo <command> <opts>
Command
What it does
fetch