Merge pull request #1175 from rust-lang/introduction

Introduction/Chapter 1 edits
This commit is contained in:
Carol (Nichols || Goulding)
2018-02-21 11:05:44 -05:00
committed by GitHub
9 changed files with 769 additions and 917 deletions

View File

@@ -1,169 +1,51 @@
[TOC]
# Introduction
# Getting Started
Welcome to “The Rust Programming Language,” an introductory book about Rust.
<!-- If you want to use this paragraph in the Introduction, can you replace it
with some other introductory text for the chapter here? Maybe just lay out
what's in this chapter so they know it's important not to skip it. -->
<!-- Yep, done! /Carol -->
Rust is a programming language that helps you write faster, more reliable
software. High-level ergonomics and low-level control are often at odds with
each other in programming language design; Rust stands to challenge that.
Through balancing powerful technical capacity and a great developer experience,
Rust gives you the option to control low-level details (such as memory usage)
without all the hassle traditionally associated with such control.
Lets get your Rust journey started! In this chapter, well discuss:
## Who Rust is For
Rust is great for many people for a variety of reasons. Lets discuss a few of
the most important groups.
### Teams of Developers
Rust is proving to be a productive tool for collaborating among large teams of
developers with varying levels of systems programming knowledge. Low-level code
is prone to a variety of subtle bugs, which in most other languages can only be
caught through extensive testing and careful code review by experienced
developers. In Rust, the compiler plays a gatekeeper role by refusing to
compile code with these kinds of bugs--including concurrency bugs. By working
alongside the compiler, the team can spend more time focusing on the logic of
the program rather than chasing down bugs.
Rust also brings contemporary developer tools to the systems programming world:
* Cargo, the included dependency manager and build tool, makes adding,
compiling, and managing dependencies painless and consistent across the Rust
ecosystem.
* Rustfmt ensures a consistent coding style across developers.
* The Rust Language Server powers IDE integration for code completion and
inline error messages.
By using these and other tools in the Rust ecosystem, developers can be
productive while writing systems-level code.
### Students
Rust is for students and people who are interested in learning about systems
concepts. Many people have learned about topics like operating systems
development through Rust. The community is happy to answer student questions.
Through efforts such as this book, the Rust teams want to make systems concepts
more accessible to more people, especially those getting started with
programming.
### Companies
Rust is used in production by hundreds of companies, large and small, for a
variety of tasks, such as command line tools, web services, DevOps tooling,
embedded devices, audio and video analysis and transcoding, cryptocurrencies,
bioinformatics, search engines, internet of things applications, machine
learning, and even major parts of the Firefox web browser.
### Open Source Developers
Rust is for people who want to build the Rust programming language, community,
developer tools, and libraries. Wed love for you to contribute to the Rust
language.
### People Who Value Speed and Stability
By speed, we mean both the speed of the programs that Rust lets you create and
the speed at which Rust lets you write them. The Rust compilers checks ensure
stability through feature additions and refactoring, as opposed to brittle
legacy code in languages without these checks that developers are afraid to
modify. By striving for zero-cost abstractions, higher level features that
compile to lower level code as fast as code written manually, Rust endeavors to
make safe code be fast code as well.
This isnt a complete list of everyone the Rust language hopes to support, but
these are some of the biggest stakeholders. Overall, Rusts greatest ambition
is to take trade-offs that have been accepted by programmers for decades and
eliminate the dichotomy. Safety *and* productivity. Speed *and* ergonomics.
Give Rust a try, and see if its choices work for you.
## Who This Book is For
This book assumes that youve written code in some other programming language,
but doesnt make any assumptions about which one. Weve tried to make the
material broadly accessible to those from a wide variety of programming
backgrounds. We dont spend a lot of time talking about what programming *is*
or how to think about it; someone new to programming entirely would be better
served by reading a book specifically providing an introduction to programming.
## How to Use This Book
This book generally assumes that youre reading it front-to-back, that is,
later chapters build on top of concepts in earlier chapters, and earlier
chapters may not dig into details on a topic, revisiting the topic in a later
chapter.
There are two kinds of chapters in this book: concept chapters, and project
chapters. In concept chapters, youll learn about an aspect of Rust. In the
project chapters, well build small programs together, applying what weve
learned so far. Chapters 2, 12, and 20 are project chapters; the rest are
concept chapters.
Additionally, Chapter 2 is a hands-on introduction to Rust as a language. Well
cover concepts at a high level, and later chapters will go into them in detail.
If youre the kind of person who likes to get their hands dirty right away,
Chapter 2 is great for that. If youre *really* that kind of person, you may
even wish to skip over Chapter 3, which covers features that are very similar
to other programming languages, and go straight to Chapter 4 to learn about
Rusts ownership system. By contrast, if youre a particularly meticulous
learner who prefers to learn every detail before moving onto the next, you may
want to skip Chapter 2 and go straight to Chapter 3.
In the end, theres no wrong way to read a book: if you want to skip ahead, go
for it! You may have to jump back if you find things confusing. Do whatever
works for you.
An important part of the process of learning Rust is learning how to read the
error messages that the compiler gives you. As such, well be showing a lot of
code that doesnt compile, and the error message the compiler will show you in
that situation. As such, if you pick a random example, it may not compile!
Please read the surrounding text to make sure that you didnt happen to pick
one of the in-progress examples.
Finally, there are some appendices. These contain useful information about the
language in a more reference-like format.
## Contributing to the Book
This book is open source. If you find an error, please dont hesitate to file
an issue or send a pull request on GitHub at
*https://github.com/rust-lang/book*. Please see CONTRIBUTING.md at
*https://github.com/rust-lang/book/blob/master/CONTRIBUTING.md* for more
details.
- Installing Rust on Linux, Mac, or Windows
- Writing a program that prints “Hello, world!”
- Using `cargo`, Rusts package manager and build system
## Installation
The first step to using Rust is to install it. Youll need an internet
connection to run the commands in this chapter, as well be downloading Rust
from the internet. Well actually be installing Rust using `rustup`, a
command-line tool for managing Rust versions and associated tools.
The first step to using Rust is to install it. Well download Rust through
`rustup`, a command-line tool for managing Rust versions and associated tools.
For this youll need an internet connection.
The following steps will install the latest stable version of the Rust
compiler. The examples and output shown in this book used stable Rust 1.21.0.
Due to Rusts stability guarantees, which well discuss further in the “How
Rust is Made” section later in this chapter, all of the examples that compile
will continue to compile with newer versions of Rust. The output may differ
slightly as error messages and warnings are often improved. In other words, the
newer, stable version of Rust you will install with these steps should work as
expected with the content of this book.
compiler. The examples and output shown in this book all use stable Rust
1.21.0. Rusts stability guarantees ensure that all of the examples in the book
that compile will continue to compile with newer versions of Rust. The output
may differ slightly between versions, as error messages and warnings are often
improved. In other words, any newer, stable version of Rust you will install
with these steps should work as expected with the content of this book.
<!-- PROD: Start Box -->
> #### Command Line Notation
>
> Well be showing off a number of commands using a terminal, and those lines
> all start with `$`. You dont need to type in the `$` character; they are
> there to indicate the start of each command. Youll see many tutorials and
> examples around the web that follow this convention: `$` for commands run as
> a regular user, and `#` for commands you should be running as an
> administrator. Lines that dont start with `$` are typically showing the
> output of the previous command. Additionally, PowerShell specific examples
> will use `>` rather than `$`.
> In this chapter and throughout the book well be showing some commands used
> in the terminal. Lines that should be entered in a terminal all start with
> `$`. You dont need to type in the `$` character, it is simply there to
> indicate the start of each command. Many tutorials use this convention: `$`
> for commands run as a regular user, and `#` for commands you should be
> running as an administrator. Lines that dont start with `$` are typically
> showing the output of the previous command. Additionally, PowerShell specific
> examples will use `>` rather than `$`.
<!-- PROD: End box -->
### Installing Rustup on Linux or Mac
If youre on Linux or a Mac, 99% of what you need to do is open a terminal and
type this:
If youre on Linux or a Mac, open a terminal and enter the following command:
```
$ curl https://sh.rustup.rs -sSf | sh
@@ -181,38 +63,43 @@ Of course, if you distrust using `curl URL | sh` to install software, you can
download, inspect, and run the script however you like.
The installation script automatically adds Rust to your system PATH after your
next login. If you want to start using Rust right away, run the following
command in your shell:
next login. If you want to start using Rust right away instead of restarting
your terminal, run the following command in your shell to add Rust to your
system PATH manually:
<!-- what does this command do? Do you mean instead of logging out and logging
in, enter the following? -->
<!-- It runs a script that adds Rust to your system PATH manually. I've
clarified that yes, this is instead of logging out and back in to your
terminal. /Carol -->
```
$ source $HOME/.cargo/env
```
Alternatively, add the following line to your `~/.bash_profile`:
Alternatively, you can add the following line to your `~/.bash_profile`:
```
$ export PATH="$HOME/.cargo/bin:$PATH"
```
Finally, youll need a linker of some kind. You likely have one installed. If
not, when you compile a Rust program, youll get errors that a linker could not
be executed. Check your platforms documentation for how to install a C
compiler; they usually come with the correct linker as well, given that C needs
one. You may want to install a C compiler regardless of your need for only a
linker; some common Rust packages depend on C code and will need a C compiler
too.
Finally, youll need a linker of some kind. Its likely you already have one
installed, but if you try to compile a Rust program and get errors telling you
that a linker could not be executed, youll need to install one. You can
install a C compiler, as that will usually come with the correct linker. Check
your platforms documentation for how to install a C compiler. Some common Rust
packages depend on C code and will need a C compiler too, so it may be worth
installing one now regardless.
### Installing Rustup on Windows
On Windows, go to https://www.rust-lang.org/en-US/install.html at
*https://www.rust-lang.org/en-US/install.html* and follow the instructions.
Youll also need the C++ build tools for Visual Studio 2013 or later. The
easiest way to acquire the build tools is by installing Build Tools for Visual
Studio 2017 at *https://www.visualstudio.com/downloads/* which provides only
the Visual C++ build tools. Alternately, you can install at
*https://www.visualstudio.com/downloads/* Visual Studio 2017, Visual Studio
2015, or Visual Studio 2013 and during installation select the desktop
development with C++ workload.
On Windows, go to *https://www.rust-lang.org/en-US/install.html* and follow the
instructions for installing Rust. At some point in the installation youll
receive a message telling you youll also need the C++ build tools for Visual
Studio 2013 or later. The easiest way to acquire the build tools is to install
Build Tools for Visual Studio 2017 at
*https://www.visualstudio.com/downloads/*, found in the Other Tools and
Frameworks section.
The rest of this book will use commands that work in both `cmd.exe` and
PowerShell. If there are specific differences, well explain which to use.
@@ -222,7 +109,7 @@ PowerShell. If there are specific differences, well explain which to use.
If you have reasons for preferring not to use `rustup`, please see the Rust
installation page at *https://www.rust-lang.org/install.html* for other options.
### Updating
### Updating and Uninstalling
Once you have Rust installed via `rustup`, updating to the latest version is
easy. From your shell, run the update script:
@@ -231,10 +118,7 @@ easy. From your shell, run the update script:
$ rustup update
```
### Uninstalling
Uninstalling Rust and Rustup is as easy as installing them. From your shell,
run the uninstall script:
To uninstall Rust and `rustup`, from your shell, run the uninstall script:
```
$ rustup self uninstall
@@ -242,14 +126,14 @@ $ rustup self uninstall
### Troubleshooting
To check that you have Rust installed, you can open up a shell and type this:
To check whether you have Rust installed correctly, open up a shell and enter:
```
$ rustc --version
```
You should see the version number, commit hash, and commit date in a format
similar to this for the latest stable version at the time you install:
You should see the version number, commit hash, and commit date for the latest
stable version at the time you install in the following format:
```
rustc x.y.z (abcabcabc yyyy-mm-dd)
@@ -260,9 +144,9 @@ If you see this, Rust has been installed successfully! Congrats!
If you dont and youre on Windows, check that Rust is in your `%PATH%` system
variable.
If it still isnt working, there are a number of places where you can get help.
The easiest is the #rust IRC channel on irc.mozilla.org, which you can access
through Mibbit at
If thats all correct and Rust still isnt working, there are a number of
places you can get help. The easiest is the #rust IRC channel on
irc.mozilla.org, which you can access through Mibbit at
*http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust*. Go to that
address, and youll be chatting with other Rustaceans (a silly nickname we call
ourselves) who can help you out. Other great resources include the Users forum
@@ -283,8 +167,7 @@ Interface) documentation to find out!
Now that you have Rust installed, lets write your first Rust program. Its
traditional when learning a new language to write a little program to print the
text “Hello, world!” to the screen, and in this section, well follow that
tradition.
text “Hello, world!” to the screen, so well do the same here!
> Note: This book assumes basic familiarity with the command line. Rust itself
> makes no specific demands about your editing, tooling, or where your code
@@ -297,10 +180,12 @@ tradition.
### Creating a Project Directory
First, make a directory to put your Rust code in. Rust doesnt care where your
code lives, but for this book, wed suggest making a *projects* directory in
your home directory and keeping all your projects there. Open a terminal and
enter the following commands to make a *projects* directory and a directory
inside that for the “Hello, world!” project:
code lives, but for the exercises and projects in this book, wed suggest
making a *projects* directory in your home directory and keeping all your
projects there.
Open a terminal and enter the following commands to make a *projects* directory
and, inside that, a directory for this “Hello, world!” project:
Linux and Mac:
@@ -331,7 +216,7 @@ Windows PowerShell:
### Writing and Running a Rust Program
Next, make a new source file and call it *main.rs*. Rust files always end with
Next, make a new source file and call it *main.rs*---Rust files always end with
the *.rs* extension. If youre using more than one word in your filename, use
an underscore to separate them. For example, youd use *hello_world.rs* rather
than *helloworld.rs*.
@@ -350,7 +235,7 @@ fn main() {
Listing 1-1: A program that prints “Hello, world!”
Save the file, and go back to your terminal window. On Linux or macOS, enter
the following commands:
the following commands to compile and run the file:
```
$ rustc main.rs
@@ -367,9 +252,17 @@ Hello, world!
```
Regardless of your operating system, you should see the string `Hello, world!`
print to the terminal. If you did, then congratulations! Youve officially
print to the terminal. If you dont see this output, see the “Troubleshooting”
section earlier for ways to get help.
If you did see `Hello, world!` printed, then congratulations! Youve officially
written a Rust program. That makes you a Rust programmer! Welcome!
<!-- Any quick words of advice for if they didn't? (Disclosure: I tried
following this using Bash on windows and couldn't get it working) -->
<!-- Added a pointer to the previous troubleshooting section which also applies
here /Carol -->
### Anatomy of a Rust Program
Now, lets go over what just happened in your “Hello, world!” program in
@@ -381,14 +274,15 @@ fn main() {
}
```
These lines define a *function* in Rust. The `main` function is special: its
the first code that is run for every executable Rust program. The first line
declares a function named `main` that has no parameters and returns nothing. If
there were parameters, their names would go inside the parentheses, `(` and `)`.
These lines define a *function* in Rust. The `main` function is special: it is
always the first code that is run for every executable Rust program. The first
line declares a function named `main` that has no parameters and returns
nothing. If there were parameters, their names would go inside the parentheses,
`(` and `)`.
Also note that the function body is wrapped in curly brackets, `{` and `}`.
Rust requires these around all function bodies. Its considered good style to
put the opening curly bracket on the same line as the function declaration,
place the opening curly bracket on the same line as the function declaration,
with one space in between.
> At the time of writing, an automatic formatter, `rustfmt`, is under
@@ -408,46 +302,35 @@ This line does all of the work in this little program: it prints text to the
screen. There are a number of details to notice here. The first is that Rust
style is to indent with four spaces, not a tab.
The second important part is `println!`. This is calling a Rust *macro*, which
is how metaprogramming is done in Rust. If it were calling a function instead,
it would look like this: `println` (without the `!`). Well discuss Rust macros
in more detail in Appendix D, but for now you just need to know that when you
see a `!` that means that youre calling a macro instead of a normal function.
The second important detail is the `println!` call. This code is calling a Rust
*macro*. If it were calling a function instead, it would be entered as
`println` (without the `!`). Well discuss Rust macros in more detail in
Appendix D, but for now you just need to know that when you see a `!` that
means that youre calling a macro instead of a normal function.
> ### Why `println!` is a Macro
>
> There are multiple reasons why `println!` is a macro rather than a function,
> and we havent really explained Rust yet, so its not exactly obvious. Here
> are the reasons:
>
> * The string passed to `println!` can have formatting specifiers in it,
> and those are checked at compile-time.
> * Rust functions can only have a fixed number of arguments, but `println!`
> (and macros generally) can take a variable number.
> * The formatting specifiers can have named arguments, which Rust functions
> cannot.
> * It implicitly takes its arguments by reference even when theyre passed
> by value.
>
> If none of this makes sense, dont worry about it. Well cover these concepts
> in more detail later.
<!-- I might suggest just cutting this next macro section -- for the sake of
the intro, we don't really need this info, and I feel like this first exercise
should be short and sweet and simple -->
<!-- I'm ok with cutting this; it's a fairly common question that some folks
have at this point, but I'm ok with those people having to do some research
online if they're curious /Carol -->
Next is `"Hello, world!"` which is a *string*. We pass this string as an
argument to `println!`, which prints the string to the screen. Easy enough!
Next comes`"Hello, world!"` which is a *string*. We pass this string as an
argument to `println!` and the total effect is that the string is printed to
the screen. Easy enough!
The line ends with a semicolon (`;`). The `;` indicates that this expression is
We end the line with a semicolon `;`, which indicates that this expression is
over, and the next one is ready to begin. Most lines of Rust code end with a
`;`.
### Compiling and Running Are Separate Steps
In the “Writing and Running a Rust Program section on page XX, we showed you
how to run a newly created program. Well break that process down and examine
each step now.
Youve just seen how to run a newly created program, so now lets break that
process down and examine each step.
Before running a Rust program, you have to compile it. You can use the Rust
compiler by entering the `rustc` command and passing it the name of your source
file, like this:
Before running a Rust program, you have to compile it using the Rust compiler
by entering the `rustc` command and passing it the name of your source file,
like this:
```
$ rustc main.rs
@@ -495,30 +378,29 @@ hand, they need to have a Ruby, Python, or JavaScript implementation installed
program. Everything is a tradeoff in language design.
Just compiling with `rustc` is fine for simple programs, but as your project
grows, youll want to be able to manage all of the options your project has and
make it easy to share your code with other people and projects. Next, well
introduce you to a tool called Cargo, which will help you write real-world Rust
programs.
grows, youll want to be able to manage all of the options and make it easy to
share your code. Next, well introduce you to a tool called Cargo, which will
help you write real-world Rust programs.
## Hello, Cargo!
Cargo is Rusts build system and package manager, and Rustaceans use Cargo to
manage their Rust projects because it makes a lot of tasks easier. For example,
Cargo takes care of building your code, downloading the libraries your code
depends on, and building those libraries. We call libraries your code needs
*dependencies*.
Cargo is Rusts build system and package manager. Most Rustaceans will use this
tool to manage their Rust projects because Cargo takes care of a lot of tasks
for you, such as building your code, downloading the libraries your code
depends on, and building those libraries. (We call libraries your code needs
*dependencies*.)
The simplest Rust programs, like the one weve written so far, dont have any
dependencies, so right now, youd only be using the part of Cargo that can take
care of building your code. As you write more complex Rust programs, youll
want to add dependencies, and if you start off using Cargo, that will be a lot
easier to do.
dependencies, so if we had built the Hello World project with Cargo, it would
only be using the part of Cargo that takes care of building your code. As you
write more complex Rust programs, youll want to add dependencies, and if you
start the project off using Cargo, that will be a lot easier to do.
As the vast, vast majority of Rust projects use Cargo, we will assume that
youre using it for the rest of the book. Cargo comes installed with Rust
itself, if you used the official installers as covered in the “Installation”
section. If you installed Rust through some other means, you can check if you
have Cargo installed by typing the following into your terminal:
As the vast majority of Rust projects use Cargo, the rest of this book will
assume that youre using Cargo too. Cargo comes installed with Rust itself, if
you used the official installers as covered in the “Installation” section. If
you installed Rust through some other means, you can check if you have Cargo
installed by entering the following into your terminal:
```
$ cargo --version
@@ -531,41 +413,39 @@ installation to determine how to install Cargo separately.
### Creating a Project with Cargo
Lets create a new project using Cargo and look at how it differs from our
project in `hello_world`. Go back to your projects directory (or wherever you
decided to put your code):
Linux, Mac, and PowerShell:
```
$ cd ~/projects
```
CMD for Windows:
```
> cd \d "%USERPROFILE%\projects"
```
And then on any operating system run:
original Hello World project. Navigate back to your *projects* directory (or
wherever you decided to put your code) and then on any operating system run:
```
$ cargo new hello_cargo --bin
$ cd hello_cargo
```
We passed the `--bin` argument to `cargo new` because our goal is to make an
executable application, as opposed to a library. Executables are binary
executable files often called just *binaries*. Weve given `hello_cargo` as the
name for our project, and Cargo creates its files in a directory of the same
name that we can then go into.
<!-- Below -- so we always have to start a cargo project with the --bin option
if we want it to be something we can execute and not just a library, is that
right? It might be worth laying that out -->
<!-- As of Rust 1.21.0 (the version we're using for the book), yes, you must
always specify `--bin`. In a version of Rust in the near future (1.25 or 1.26),
binary crates will become the default kind of crate that `cargo new` makes, so
you won't have to specify `--bin` (but you can if you want and the behavior
will be the same). We'd rather not go into any more detail than we have here
because of this change; I think "The `--bin` argument to passed to `cargo new`
makes an executable application (often just called a *binary*), as opposed to a
library." lays this out enough. /Carol -->
If we list the files in the *hello_cargo* directory, we can see that Cargo has
generated two files and one directory for us: a *Cargo.toml* and a *src*
directory with a *main.rs* file inside. It has also initialized a new git
repository in the *hello_cargo* directory for us, along with a *.gitignore*
file. Git is a common version control system. You can change `cargo new` to use
a different version control system, or no version control system, by using the
`--vcs` flag. Run `cargo new --help` to see the available options.
This creates a new binary executable called `hello_cargo`. The `--bin` argument
to passed to `cargo new` makes an executable application (often just called a
*binary*), as opposed to a library. Weve given `hello_cargo` as the name for
our project, and Cargo creates its files in a directory of the same name.
Go into the *hello_cargo* directory and list the files, and you should see that
Cargo has generated two files and one directory for us: a *Cargo.toml* and a
*src* directory with a *main.rs* file inside. It has also initialized a new git
repository, along with a *.gitignore* file.
> Note: Git is a common version control system. You can change `cargo new` to
> use a different version control system, or no version control system, by
> using the `--vcs` flag. Run `cargo new --help` to see the available options.
Open up *Cargo.toml* in your text editor of choice. It should look similar to
the code in Listing 1-2:
@@ -583,26 +463,24 @@ authors = ["Your Name <you@example.com>"]
Listing 1-2: Contents of *Cargo.toml* generated by `cargo new`
This file is in the *TOML* (Toms Obvious, Minimal Language) format. TOML is
used as Cargos configuration format.
This file is in the *TOML* (Toms Obvious, Minimal Language) format, which is
what Cargo uses as its configuration format.
The first line, `[package]`, is a section heading that indicates that the
following statements are configuring a package. As we add more information to
this file, well add other sections.
The next three lines set the three bits of configuration that Cargo needs to
see in order to know that it should compile your program: its name, what
version it is, and who wrote it. Cargo gets your name and email information
from your environment. If its not correct, go ahead and fix that and save the
file.
The next three lines set the configuration information Cargo needs in order to
know that it should compile your program: the name, the version, and who wrote
it. Cargo gets your name and email information from your environment, so if
thats not correct, go ahead and fix that and save the file.
The last line, `[dependencies]`, is the start of a section for you to list any
*crates* (which is what we call packages of Rust code) that your project will
depend on so that Cargo knows to download and compile those too. We wont need
any other crates for this project, but we will in the guessing game tutorial in
Chapter 2.
of your projects dependencies. In Rust, packages of code are referred to as
*crates*. We wont need any other crates for this project, but we will in the
first project in Chapter 2, so well use this dependencies section then.
Now lets look at *src/main.rs*:
Now open up *src/main.rs* and take a look:
Filename: src/main.rs
@@ -613,11 +491,9 @@ fn main() {
```
Cargo has generated a “Hello World!” for you, just like the one we wrote in
Listing 1-1! So that part is the same. The differences between our previous
project and the project generated by Cargo that weve seen so far are:
- Our code goes in the *src* directory
- The top level contains a *Cargo.toml* configuration file
Listing 1-1! So far, the differences between our previous project and the
project generated by Cargo are that with Cargo our code goes in the *src*
directory, and we have a *Cargo.toml* configuration file in the top directory.
Cargo expects your source files to live inside the *src* directory so that the
top-level project directory is just for READMEs, license information,
@@ -627,13 +503,14 @@ everything, and everything is in its place.
If you started a project that doesnt use Cargo, as we did with our project in
the *hello_world* directory, you can convert it to a project that does use
Cargo by moving your code into the *src* directory and creating an appropriate
*Cargo.toml*.
Cargo by moving the project code into the *src* directory and creating an
appropriate *Cargo.toml*.
### Building and Running a Cargo Project
Now lets look at whats different about building and running your Hello World
program through Cargo! To do so, enter the following commands:
program through Cargo! From your project directory, build your project by
entering the following commands:
```
$ cargo build
@@ -651,16 +528,15 @@ Hello, world!
```
Bam! If all goes well, `Hello, world!` should print to the terminal once more.
Running `cargo build` for the first time also causes Cargo to create a new file
at the top level called *Cargo.lock*. Cargo uses *Cargo.lock* to keep track of
the exact versions of dependencies used to build your project. This project
doesnt have dependencies, so the file is a bit sparse. You wont ever need to
touch this file yourself; Cargo will manage its contents for you.
at the top level called *Cargo.lock*, which is used to keep track of the exact
versions of dependencies in your project. This project doesnt have
dependencies, so the file is a bit sparse. You wont ever need to touch this
file yourself; Cargo will manage its contents for you.
We just built a project with `cargo build` and ran it with
`./target/debug/hello_cargo`, but we can also use `cargo run` to compile and
then run:
then run all in one go:
```
$ cargo run
@@ -672,8 +548,7 @@ Hello, world!
Notice that this time, we didnt see the output telling us that Cargo was
compiling `hello_cargo`. Cargo figured out that the files havent changed, so
it just ran the binary. If you had modified your source code, Cargo would have
rebuilt the project before running it, and you would have seen output like
this:
rebuilt the project before running it, and you would have seen output like this:
```
$ cargo run
@@ -683,8 +558,8 @@ $ cargo run
Hello, world!
```
Finally, theres `cargo check`. This will quickly check your code to make sure
that it compiles, but not bother producing an executable:
Finally, theres `cargo check`. This command will quickly check your code to
make sure that it compiles, but not bother producing an executable:
```
$ cargo check
@@ -693,20 +568,20 @@ $ cargo check
```
Why would you not want an executable? `cargo check` is often much faster than
`cargo build`, because Cargo can skip the entire step of producing the
executable. If were checking our work throughout the process of writing the
code, this will speed things up! As such, many Rustaceans run `cargo check` as
they write their program to make sure that it compiles, and then run `cargo
build` once theyre ready to give it a spin themselves.
`cargo build`, because it skips the entire step of producing the executable. If
youre checking your work throughout the process of writing the code, using
`cargo check` will speed things up! As such, many Rustaceans run `cargo check`
periodically as they write their program to make sure that it compiles, and
then run `cargo build` once theyre ready to give it a spin themselves.
So a few more differences weve now seen:
So to recap, using Cargo:
- Instead of using `rustc`, build a project using `cargo build` or
`cargo check` (or build and run it in one step with `cargo run`).
- We can build a project using `cargo build` or `cargo check`
- We can build and run the project in one step with `cargo run`
- Instead of the result of the build being put in the same directory as our
code, Cargo will put it in the *target/debug* directory.
The other advantage of using Cargo is that the commands are the same no matter
A final advantage of using Cargo is that the commands are the same no matter
what operating system youre on, so at this point we will no longer be
providing specific instructions for Linux and Mac versus Windows.
@@ -718,24 +593,22 @@ executable in *target/release* instead of *target/debug*. These optimizations
make your Rust code run faster, but turning them on makes your program take
longer to compile. This is why there are two different profiles: one for
development when you want to be able to rebuild quickly and often, and one for
building the final program youll give to a user that wont be rebuilt and that
we want to run as fast as possible. If youre benchmarking the running time of
your code, be sure to run `cargo build --release` and benchmark with the
executable in *target/release*.
building the final program youll give to a user that wont be rebuilt
repeatedly and that will run as fast as possible. If youre benchmarking the
running time of your code, be sure to run `cargo build --release` and benchmark
with the executable in *target/release*.
### Cargo as Convention
With simple projects, Cargo doesnt provide a whole lot of value over just
using `rustc`, but it will prove its worth as you continue. With complex
projects composed of multiple crates, its much easier to let Cargo coordinate
the build. With Cargo, you can just run `cargo build`, and it should work the
right way.
the build.
Even though the `hello_cargo` project is simple, it now uses much of the real
tooling youll use for the rest of your Rust career. In fact, you can get
started with virtually all Rust projects you want to work on with the following
commands to check out the code using Git, change into the project directory,
and build:
tooling youll use for the rest of your Rust career. In fact, to work on any
existing projects you can use the following commands to check out the code
using Git, change into the project directory, and build:
```
$ git clone someurl.com/someproject
@@ -744,228 +617,27 @@ $ cargo build
```
If you want to look at Cargo in more detail, check out its documentation at
*https://doc.rust-lang.org/cargo/*, which covers all of its features.
*https://doc.rust-lang.org/cargo/*.
## How Rust is Made and “Nightly Rust”
Before we dive into the language itself, wed like to finish up the
introductory chapter by talking about how Rust is made, and how that affects
you as a Rust developer. We mentioned in the “Installation” section that the
output in this book was generated by stable Rust 1.21.0, but any examples that
compile should continue to compile in any stable version of Rust greater than
that. This section is to explain how we ensure this is true!
### Stability Without Stagnation
As a language, Rust cares a *lot* about the stability of your code. We want
Rust to be a rock-solid foundation you can build on, and if things were
constantly changing, that would be impossible. At the same time, if we cant
experiment with new features, we may not find out important flaws until after
their release, when we can no longer change things.
Our solution to this problem is what we call “stability without stagnation” and
is the way we can change and improve Rust while making sure that using Rust
stays nice, stable, and boring.
Our guiding principle for Rust releases is this: you should never have to fear
upgrading to a new version of stable Rust. Each upgrade should be painless. At
the same time, the upgrade should bring you new features, fewer bugs, and
faster compile times.
### Choo, Choo! Release Channels and Riding the Trains
Rust development operates on a *train schedule*. That is, all development is
done on the `master` branch of the Rust repository. Releases follow a software
release train model, which has been used by Cisco IOS and other software
projects. There are three *release channels* for Rust:
* Nightly
* Beta
* Stable
Most Rust developers primarily use the stable channel, but those who want to
try out experimental new features may use nightly or beta.
Heres an example of how the development and release process works: lets
assume that the Rust team is working on the release of Rust 1.5. That release
happened in December of 2015, but it will provide us with realistic version
numbers. A new feature is added to Rust: a new commit lands on the `master`
branch. Each night, a new nightly version of Rust is produced. Every day is a
release day, and these releases are created by our release infrastructure
automatically. So as time passes, our releases look like this, once a night:
```
nightly: * - - * - - *
```
Every six weeks, its time to prepare a new release! The `beta` branch of the
Rust repository branches off from the `master` branch used by nightly. Now,
there are two releases:
```
nightly: * - - * - - *
|
beta: *
```
Most Rust users do not use beta releases actively, but test against beta in
their CI system to help Rust discover possible regressions. In the meantime,
theres still a nightly release every night:
```
nightly: * - - * - - * - - * - - *
|
beta: *
```
Lets say a regression is found. Good thing we had some time to test the beta
release before the regression snuck into a stable release! The fix is applied
to `master`, so that nightly is fixed, and then the fix is backported to the
`beta` branch, and a new release of beta is produced:
```
nightly: * - - * - - * - - * - - * - - *
|
beta: * - - - - - - - - *
```
Six weeks after the first beta was created, its time for a stable release! The
`stable` branch is produced from the `beta` branch:
```
nightly: * - - * - - * - - * - - * - - * - * - *
|
beta: * - - - - - - - - *
|
stable: *
```
Hooray! Rust 1.5 is done! However, weve forgotten one thing: because the six
weeks have gone by, we also need a new beta of the *next* version of Rust, 1.6.
So after `stable` branches off of `beta`, the next version of `beta` branches
off of `nightly` again:
```
nightly: * - - * - - * - - * - - * - - * - * - *
| |
beta: * - - - - - - - - * *
|
stable: *
```
This is called the “train model” because every six weeks, a release “leaves the
station”, but still has to take a journey through the beta channel before it
arrives as a stable release.
Rust releases every six weeks, like clockwork. If you know the date of one Rust
release, you can know the date of the next one: its six weeks later. A nice
aspect of having releases scheduled every six weeks is that the next train is
coming soon. If a feature happens to miss a particular release, theres no need
to worry: another one is happening in a short time! This helps reduce pressure
to sneak possibly unpolished features in close to the release deadline.
Thanks to this process, you can always check out the next build of Rust and
verify for yourself that its easy to upgrade to: if a beta release doesnt
work as expected, you can report it to the team and get it fixed before the
next stable release happens! Breakage in a beta release is relatively rare, but
`rustc` is still a piece of software, and bugs do exist.
### Unstable Features
Theres one more catch with this release model: unstable features. Rust uses a
technique called “feature flags” to determine what features are enabled in a
given release. If a new feature is under active development, it lands on
`master`, and therefore, in nightly, but behind a *feature flag*. If you, as a
user, wish to try out the work-in-progress feature, you can, but you must be
using a nightly release of Rust and annotate your source code with the
appropriate flag to opt in.
If youre using a beta or stable release of Rust, you cant use any feature
flags. This is the key that allows us to get practical use with new features
before we declare them stable forever. Those who wish to opt into the bleeding
edge can do so, and those who want a rock-solid experience can stick with
stable and know that their code wont break. Stability without stagnation.
This book only contains information about stable features, as in-progress
features are still changing, and surely theyll be different between when this
book was written and when they get enabled in stable builds. You can find
documentation for nightly-only features online.
### Rustup and the Role of Rust Nightly
Rustup makes it easy to change between different release channels of Rust, on a
global or per-project basis. By default, youll have stable Rust installed. To
install nightly, for example:
```
$ rustup install nightly
```
You can see all of the *toolchains* (releases of Rust and associated
components) you have installed with `rustup` as well. Heres an example on one
of your authors computers:
```
> rustup toolchain list
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc
```
As you can see, the stable toolchain is the default. Most Rust users use stable
most of the time. You might want to use stable most of the time, but use
nightly on a specific project, because you care about a cutting-edge feature.
To do so, you can use `rustup override` in that projects directory to set the
nightly toolchain as the one `rustup` should use when youre in that directory:
```
$ cd ~/projects/needs-nightly
$ rustup override add nightly
```
Now, every time you call `rustc` or `cargo` inside of
*~/projects/needs-nightly*, `rustup` will make sure that you are using nightly
Rust, rather than your default of stable Rust. This comes in handy when you
have a lot of Rust projects!
### The RFC Process and Teams
So how do you learn about these new features? Rusts development model follows
a *Request For Comments (RFC) process*. If youd like an improvement in Rust,
you can write up a proposal, called an RFC.
Anyone can write RFCs to improve Rust, and the proposals are reviewed and
discussed by the Rust team, which is comprised of many topic subteams. Theres
a full list of the teams on Rusts
website at *https://www.rust-lang.org/en-US/team.html*, which includes teams for
each area of the project: language design, compiler implementation,
infrastructure, documentation, and more. The appropriate team reads the
proposal and the comments, writes some comments of their own, and eventually,
theres consensus to accept or reject the feature.
If the feature is accepted, an issue is opened on the Rust repository, and
someone can implement it. The person who implements it very well may not be the
person who proposed the feature in the first place! When the implementation is
ready, it lands on the `master` branch behind a feature gate, as we discussed
in the “Unstable Features” section.
After some time, once Rust developers who use nightly releases have been able
to try out the new feature, team members will discuss the feature, how its
worked out on nightly, and decide if it should make it into stable Rust or not.
If the decision is to move forward, the feature gate is removed, and the
feature is now considered stable! It rides the trains into a new stable release
of Rust.
<!--Below -- I`m not sure this is the place for this conversation, it seems too
deep into the weeds for the "getting started" chapter. I know we discussed
Nightly Rust as an appendix previously, but honestly I think this is more
suited somewhere online, perhaps in the extended docs. I like the idea of
finishing the chapter here, on this practical note, and I think at this point
readers will want to get stuck in anyway and may skip this and never come back
because it's buried at the end of a chapter that's not really related to it. If
it's online somewhere separate they can come to it when they're ready. What do
you think?-->
<!-- Ok, I can see that. /Carol -->
## Summary
Youre already off to a great start on your Rust journey! In this chapter,
youve:
* Learned what makes Rust unique
* Installed the latest stable version of Rust
* Written a “Hello, world!” program using both `rustc` directly and using
the conventions of `cargo`
* Found out about how Rust is developed
This is a great time to build a more substantial program, to get used to
reading and writing Rust code. In the next chapter, well build a guessing game

View File

@@ -1,3 +1,6 @@
[TOC]
# Introduction
Welcome to “The Rust Programming Language,” an introductory book about Rust.
@@ -125,8 +128,6 @@ language in a more reference-like format.
## Contributing to the Book
This book is open source. If you find an error, please dont hesitate to file
an issue or send a pull request [on GitHub]. Please see [CONTRIBUTING.md] for
an issue or send a pull request on GitHub at *https://github.com/rust-lang/book*. Please see CONTRIBUTING.md at *https://github.com/rust-lang/book/blob/master/CONTRIBUTING.md* for
more details.
[on GitHub]: https://github.com/rust-lang/book
[CONTRIBUTING.md]: https://github.com/rust-lang/book/blob/master/CONTRIBUTING.md

View File

@@ -1,11 +1,13 @@
# The Rust Programming Language
[Introduction](ch00-00-introduction.md)
## Getting started
- [Introduction](ch01-00-introduction.md)
- [Getting Started](ch01-00-getting-started.md)
- [Installation](ch01-01-installation.md)
- [Hello, World!](ch01-02-hello-world.md)
- [How Rust is Made and “Nightly Rust”](ch01-03-how-rust-is-made-and-nightly-rust.md)
- [Hello, Cargo!](ch01-03-hello-cargo.md)
- [Guessing Game Tutorial](ch02-00-guessing-game-tutorial.md)
@@ -129,3 +131,4 @@
- [D - Macros](appendix-04-macros.md)
- [E - Translations](appendix-05-translation.md)
- [F - Newest Features](appendix-06-newest-features.md)
- [G - How Rust is Made and “Nightly Rust”](appendix-07-nightly-rust.md)

View File

@@ -1,11 +1,10 @@
## How Rust is Made and “Nightly Rust”
# Appendix G - How Rust is Made and “Nightly Rust”
Before we dive into the language itself, wed like to finish up the
introductory chapter by talking about how Rust is made, and how that affects
you as a Rust developer. We mentioned in the “Installation” section that the
output in this book was generated by stable Rust 1.21.0, but any examples that
compile should continue to compile in any stable version of Rust greater than
that. This section is to explain how we ensure this is true!
This appendix is about how Rust is made and how that affects you as a Rust
developer. We mentioned that the output in this book was generated by stable
Rust 1.21.0, but any examples that compile should continue to compile in any
stable version of Rust greater than that. This section is to explain how we
ensure this is true!
### Stability Without Stagnation
@@ -15,14 +14,10 @@ constantly changing, that would be impossible. At the same time, if we cant
experiment with new features, we may not find out important flaws until after
their release, when we can no longer change things.
Our solution to this problem is what we call “stability without stagnation” and
is the way we can change and improve Rust while making sure that using Rust
stays nice, stable, and boring.
Our guiding principle for Rust releases is this: you should never have to fear
upgrading to a new version of stable Rust. Each upgrade should be painless. At
the same time, the upgrade should bring you new features, fewer bugs, and
faster compile times.
Our solution to this problem is what we call “stability without stagnation”,
and our guiding principle is this: you should never have to fear upgrading to a
new version of stable Rust. Each upgrade should be painless, but should also
bring you new features, fewer bugs, and faster compile times.
### Choo, Choo! Release Channels and Riding the Trains
@@ -207,20 +202,3 @@ worked out on nightly, and decide if it should make it into stable Rust or not.
If the decision is to move forward, the feature gate is removed, and the
feature is now considered stable! It rides the trains into a new stable release
of Rust.
## Summary
Youre already off to a great start on your Rust journey! In this chapter,
youve:
* Learned what makes Rust unique
* Installed the latest stable version of Rust
* Written a “Hello, world!” program using both `rustc` directly and using
the conventions of `cargo`
* Found out about how Rust is developed
This is a great time to build a more substantial program, to get used to
reading and writing Rust code. In the next chapter, well build a guessing game
program. If youd rather start by learning about how common programming
concepts work in Rust, see Chapter 3.

View File

@@ -0,0 +1,168 @@
# Introduction
Welcome to “The Rust Programming Language,” an introductory book about Rust.
Rust is a programming language that helps you write faster, more reliable
software. High-level ergonomics and low-level control are often at odds with
each other in programming language design; Rust stands to challenge that.
Through balancing powerful technical capacity and a great developer experience,
Rust gives you the option to control low-level details (such as memory usage)
without all the hassle traditionally associated with such control.
## Who Rust is For
Rust is great for many people for a variety of reasons. Lets discuss a few of
the most important groups.
### Teams of Developers
Rust is proving to be a productive tool for collaborating among large teams of
developers with varying levels of systems programming knowledge. Low-level code
is prone to a variety of subtle bugs, which in most other languages can only be
caught through extensive testing and careful code review by experienced
developers. In Rust, the compiler plays a gatekeeper role by refusing to
compile code with these kinds of bugs--including concurrency bugs. By working
alongside the compiler, the team can spend more time focusing on the logic of
the program rather than chasing down bugs.
Rust also brings contemporary developer tools to the systems programming world:
* Cargo, the included dependency manager and build tool, makes adding,
compiling, and managing dependencies painless and consistent across the Rust
ecosystem.
* Rustfmt ensures a consistent coding style across developers.
* The Rust Language Server powers IDE integration for code completion and
inline error messages.
By using these and other tools in the Rust ecosystem, developers can be
productive while writing systems-level code.
### Students
Rust is for students and people who are interested in learning about systems
concepts. Many people have learned about topics like operating systems
development through Rust. The community is happy to answer student questions.
Through efforts such as this book, the Rust teams want to make systems concepts
more accessible to more people, especially those getting started with
programming.
### Companies
Rust is used in production by hundreds of companies, large and small, for a
variety of tasks, such as command line tools, web services, DevOps tooling,
embedded devices, audio and video analysis and transcoding, cryptocurrencies,
bioinformatics, search engines, internet of things applications, machine
learning, and even major parts of the Firefox web browser.
### Open Source Developers
Rust is for people who want to build the Rust programming language, community,
developer tools, and libraries. Wed love for you to contribute to the Rust
language.
### People Who Value Speed and Stability
By speed, we mean both the speed of the programs that Rust lets you create and
the speed at which Rust lets you write them. The Rust compilers checks ensure
stability through feature additions and refactoring, as opposed to brittle
legacy code in languages without these checks that developers are afraid to
modify. By striving for zero-cost abstractions, higher level features that
compile to lower level code as fast as code written manually, Rust endeavors to
make safe code be fast code as well.
This isnt a complete list of everyone the Rust language hopes to support, but
these are some of the biggest stakeholders. Overall, Rusts greatest ambition
is to take trade-offs that have been accepted by programmers for decades and
eliminate the dichotomy. Safety *and* productivity. Speed *and* ergonomics.
Give Rust a try, and see if its choices work for you.
## Who This Book is For
This book assumes that youve written code in some other programming language,
but doesnt make any assumptions about which one. Weve tried to make the
material broadly accessible to those from a wide variety of programming
backgrounds. We dont spend a lot of time talking about what programming *is*
or how to think about it; someone new to programming entirely would be better
served by reading a book specifically providing an introduction to programming.
## How to Use This Book
This book generally assumes that youre reading it front-to-back, that is,
later chapters build on top of concepts in earlier chapters, and earlier
chapters may not dig into details on a topic, revisiting the topic in a later
chapter.
There are two kinds of chapters in this book: concept chapters, and project
chapters. In concept chapters, youll learn about an aspect of Rust. In the
project chapters, well build small programs together, applying what weve
learned so far. Chapters 2, 12, and 20 are project chapters; the rest are
concept chapters.
Additionally, Chapter 2 is a hands-on introduction to Rust as a language. Well
cover concepts at a high level, and later chapters will go into them in detail.
If youre the kind of person who likes to get their hands dirty right away,
Chapter 2 is great for that. If youre *really* that kind of person, you may
even wish to skip over Chapter 3, which covers features that are very similar
to other programming languages, and go straight to Chapter 4 to learn about
Rusts ownership system. By contrast, if youre a particularly meticulous
learner who prefers to learn every detail before moving onto the next, you may
want to skip Chapter 2 and go straight to Chapter 3.
Chapter 5 discusses structs and methods, and Chapter 6 covers enums, `match`
expressions, and the `if let` control flow construct. Structs and enums are the
ways to make custom types in Rust.
In Chapter 7, you'll learn about Rust's module system and privacy for
organizing your code and its public API. Chapter 8 discusses some common
collection data structures provided by the standard library: vectors, strings,
and hash maps. Chapter 9 is all about Rust's error handling philosophy and
techniques.
Chapter 10 digs into generics, traits, and lifetimes, which give you the power
to define code that applies to multiple types. Chapter 11 is all about testing,
which is still necessary even with Rust's safety guarantees to ensure your
program's logic is correct. In Chapter 12, we'll build a subset of the
functionality of the `grep` command line tool that searches for text within
files and we'll use many of the concepts we discussed in the previous chapters.
Chapter 13 explores closures and iterators: features of Rust that come from
functional programming languages. In Chapter 14, we'll explore more about Cargo
and talk about best practices for sharing your libraries with others. Chapter
15 discusses smart pointers provided by the standard library and the traits
that enable their functionality.
In Chapter 16, we'll go through different models of concurrent programming and
how Rust helps you to program using multiple threads fearlessly. Chapter 17
looks at how Rust idioms compare to Object Oriented Programming principles you
may be familiar with.
Chapter 18 is a reference on patterns and pattern matching, which are powerful
ways of expressing ideas throughout Rust programs. Chapter 19 is a smorgasbord
of advanced topics that you might be interested in, including unsafe Rust and
more about lifetimes, traits, types, functions, and closures.
In Chapter 20, we'll finish up with a project where we'll implement a low-level
multithreaded web server!
Finally, there are some appendices. These contain useful information about the
language in a more reference-like format.
In the end, theres no wrong way to read a book: if you want to skip ahead, go
for it! You may have to jump back if you find things confusing. Do whatever
works for you.
An important part of the process of learning Rust is learning how to read the
error messages that the compiler gives you. As such, well be showing a lot of
code that doesnt compile, and the error message the compiler will show you in
that situation. As such, if you pick a random example, it may not compile!
Please read the surrounding text to make sure that you didnt happen to pick
one of the in-progress examples.
## Contributing to the Book
This book is open source. If you find an error, please dont hesitate to file
an issue or send a pull request [on GitHub]. Please see [CONTRIBUTING.md] for
more details.
[on GitHub]: https://github.com/rust-lang/book
[CONTRIBUTING.md]: https://github.com/rust-lang/book/blob/master/CONTRIBUTING.md

View File

@@ -0,0 +1,12 @@
# Getting Started
<!-- If you want to use this paragraph in the Introduction, can you replace it
with some other introductory text for the chapter here? Maybe just lay out
what's in this chapter so they know it's important not to skip it. -->
<!-- Yep, done! /Carol -->
Lets get your Rust journey started! In this chapter, well discuss:
- Installing Rust on Linux, Mac, or Windows
- Writing a program that prints “Hello, world!”
- Using `cargo`, Rusts package manager and build system

View File

@@ -1,34 +1,35 @@
## Installation
The first step to using Rust is to install it. Youll need an internet
connection to run the commands in this chapter, as well be downloading Rust
from the internet. Well actually be installing Rust using `rustup`, a
command-line tool for managing Rust versions and associated tools.
The first step to using Rust is to install it. Well download Rust through
`rustup`, a command-line tool for managing Rust versions and associated tools.
For this youll need an internet connection.
The following steps will install the latest stable version of the Rust
compiler. The examples and output shown in this book used stable Rust 1.21.0.
Due to Rusts stability guarantees, which well discuss further in the “How
Rust is Made” section later in this chapter, all of the examples that compile
will continue to compile with newer versions of Rust. The output may differ
slightly as error messages and warnings are often improved. In other words, the
newer, stable version of Rust you will install with these steps should work as
expected with the content of this book.
compiler. The examples and output shown in this book all use stable Rust
1.21.0. Rusts stability guarantees ensure that all of the examples in the book
that compile will continue to compile with newer versions of Rust. The output
may differ slightly between versions, as error messages and warnings are often
improved. In other words, any newer, stable version of Rust you will install
with these steps should work as expected with the content of this book.
<!-- PROD: Start Box -->
> #### Command Line Notation
>
> Well be showing off a number of commands using a terminal, and those lines
> all start with `$`. You dont need to type in the `$` character; they are
> there to indicate the start of each command. Youll see many tutorials and
> examples around the web that follow this convention: `$` for commands run as
> a regular user, and `#` for commands you should be running as an
> administrator. Lines that dont start with `$` are typically showing the
> output of the previous command. Additionally, PowerShell specific examples
> will use `>` rather than `$`.
> In this chapter and throughout the book well be showing some commands used
> in the terminal. Lines that should be entered in a terminal all start with
> `$`. You dont need to type in the `$` character, it is simply there to
> indicate the start of each command. Many tutorials use this convention: `$`
> for commands run as a regular user, and `#` for commands you should be
> running as an administrator. Lines that dont start with `$` are typically
> showing the output of the previous command. Additionally, PowerShell specific
> examples will use `>` rather than `$`.
<!-- PROD: End box -->
### Installing Rustup on Linux or Mac
If youre on Linux or a Mac, 99% of what you need to do is open a terminal and
type this:
If youre on Linux or a Mac, open a terminal and enter the following command:
```text
$ curl https://sh.rustup.rs -sSf | sh
@@ -46,36 +47,42 @@ Of course, if you distrust using `curl URL | sh` to install software, you can
download, inspect, and run the script however you like.
The installation script automatically adds Rust to your system PATH after your
next login. If you want to start using Rust right away, run the following
command in your shell:
next login. If you want to start using Rust right away instead of restarting
your terminal, run the following command in your shell to add Rust to your
system PATH manually:
<!-- what does this command do? Do you mean instead of logging out and logging
in, enter the following? -->
<!-- It runs a script that adds Rust to your system PATH manually. I've
clarified that yes, this is instead of logging out and back in to your
terminal. /Carol -->
```text
$ source $HOME/.cargo/env
```
Alternatively, add the following line to your `~/.bash_profile`:
Alternatively, you can add the following line to your `~/.bash_profile`:
```text
$ export PATH="$HOME/.cargo/bin:$PATH"
```
Finally, youll need a linker of some kind. You likely have one installed. If
not, when you compile a Rust program, youll get errors that a linker could not
be executed. Check your platforms documentation for how to install a C
compiler; they usually come with the correct linker as well, given that C needs
one. You may want to install a C compiler regardless of your need for only a
linker; some common Rust packages depend on C code and will need a C compiler
too.
Finally, youll need a linker of some kind. Its likely you already have one
installed, but if you try to compile a Rust program and get errors telling you
that a linker could not be executed, youll need to install one. You can
install a C compiler, as that will usually come with the correct linker. Check
your platforms documentation for how to install a C compiler. Some common Rust
packages depend on C code and will need a C compiler too, so it may be worth
installing one now regardless.
### Installing Rustup on Windows
On Windows, go to [https://www.rust-lang.org/en-US/install.html][install] and
follow the instructions. Youll also need the C++ build tools for Visual Studio
2013 or later. The easiest way to acquire the build tools is by installing
[Build Tools for Visual Studio 2017][visualstudio] which provides only the
Visual C++ build tools. Alternately, you can [install][visualstudio] Visual
Studio 2017, Visual Studio 2015, or Visual Studio 2013 and during installation
select the desktop development with C++ workload.
follow the instructions for installing Rust. At some point in the installation
youll receive a message telling you youll also need the C++ build tools for
Visual Studio 2013 or later. The easiest way to acquire the build tools is to
install [Build Tools for Visual Studio 2017][visualstudio], found in the Other
Tools and Frameworks section.
[install]: https://www.rust-lang.org/en-US/install.html
[visualstudio]: https://www.visualstudio.com/downloads/
@@ -88,7 +95,7 @@ PowerShell. If there are specific differences, well explain which to use.
If you have reasons for preferring not to use `rustup`, please see [the Rust
installation page](https://www.rust-lang.org/install.html) for other options.
### Updating
### Updating and Uninstalling
Once you have Rust installed via `rustup`, updating to the latest version is
easy. From your shell, run the update script:
@@ -97,10 +104,7 @@ easy. From your shell, run the update script:
$ rustup update
```
### Uninstalling
Uninstalling Rust and Rustup is as easy as installing them. From your shell,
run the uninstall script:
To uninstall Rust and `rustup`, from your shell, run the uninstall script:
```text
$ rustup self uninstall
@@ -108,14 +112,14 @@ $ rustup self uninstall
### Troubleshooting
To check that you have Rust installed, you can open up a shell and type this:
To check whether you have Rust installed correctly, open up a shell and enter:
```text
$ rustc --version
```
You should see the version number, commit hash, and commit date in a format
similar to this for the latest stable version at the time you install:
You should see the version number, commit hash, and commit date for the latest
stable version at the time you install in the following format:
```text
rustc x.y.z (abcabcabc yyyy-mm-dd)
@@ -126,11 +130,12 @@ If you see this, Rust has been installed successfully! Congrats!
If you dont and youre on Windows, check that Rust is in your `%PATH%` system
variable.
If it still isnt working, there are a number of places where you can get help.
The easiest is [the #rust IRC channel on irc.mozilla.org][irc]<!-- ignore -->,
which you can access through [Mibbit][mibbit]. Go to that address, and youll
be chatting with other Rustaceans (a silly nickname we call ourselves) who can
help you out. Other great resources include [the Users forum][users] and [Stack
If thats all correct and Rust still isnt working, there are a number of
places you can get help. The easiest is [the #rust IRC channel on
irc.mozilla.org][irc]<!-- ignore -->, which you can access through
[Mibbit][mibbit]. Go to that address, and youll be chatting with other
Rustaceans (a silly nickname we call ourselves) who can help you out. Other
great resources include [the Users forum][users] and [Stack
Overflow][stackoverflow].
[irc]: irc://irc.mozilla.org/#rust

View File

@@ -2,8 +2,7 @@
Now that you have Rust installed, lets write your first Rust program. Its
traditional when learning a new language to write a little program to print the
text “Hello, world!” to the screen, and in this section, well follow that
tradition.
text “Hello, world!” to the screen, so well do the same here!
> Note: This book assumes basic familiarity with the command line. Rust itself
> makes no specific demands about your editing, tooling, or where your code
@@ -16,10 +15,12 @@ tradition.
### Creating a Project Directory
First, make a directory to put your Rust code in. Rust doesnt care where your
code lives, but for this book, wed suggest making a *projects* directory in
your home directory and keeping all your projects there. Open a terminal and
enter the following commands to make a *projects* directory and a directory
inside that for the “Hello, world!” project:
code lives, but for the exercises and projects in this book, wed suggest
making a *projects* directory in your home directory and keeping all your
projects there.
Open a terminal and enter the following commands to make a *projects* directory
and, inside that, a directory for this “Hello, world!” project:
Linux and Mac:
@@ -50,7 +51,7 @@ Windows PowerShell:
### Writing and Running a Rust Program
Next, make a new source file and call it *main.rs*. Rust files always end with
Next, make a new source file and call it *main.rs*---Rust files always end with
the *.rs* extension. If youre using more than one word in your filename, use
an underscore to separate them. For example, youd use *hello_world.rs* rather
than *helloworld.rs*.
@@ -69,7 +70,7 @@ fn main() {
<span class="caption">Listing 1-1: A program that prints “Hello, world!”</span>
Save the file, and go back to your terminal window. On Linux or macOS, enter
the following commands:
the following commands to compile and run the file:
```text
$ rustc main.rs
@@ -86,9 +87,17 @@ Hello, world!
```
Regardless of your operating system, you should see the string `Hello, world!`
print to the terminal. If you did, then congratulations! Youve officially
print to the terminal. If you dont see this output, see the “Troubleshooting”
section earlier for ways to get help.
If you did see `Hello, world!` printed, then congratulations! Youve officially
written a Rust program. That makes you a Rust programmer! Welcome!
<!-- Any quick words of advice for if they didn't? (Disclosure: I tried
following this using Bash on windows and couldn't get it working) -->
<!-- Added a pointer to the previous troubleshooting section which also applies
here /Carol -->
### Anatomy of a Rust Program
Now, lets go over what just happened in your “Hello, world!” program in
@@ -100,14 +109,15 @@ fn main() {
}
```
These lines define a *function* in Rust. The `main` function is special: its
the first code that is run for every executable Rust program. The first line
declares a function named `main` that has no parameters and returns nothing. If
there were parameters, their names would go inside the parentheses, `(` and `)`.
These lines define a *function* in Rust. The `main` function is special: it is
always the first code that is run for every executable Rust program. The first
line declares a function named `main` that has no parameters and returns
nothing. If there were parameters, their names would go inside the parentheses,
`(` and `)`.
Also note that the function body is wrapped in curly brackets, `{` and `}`.
Rust requires these around all function bodies. Its considered good style to
put the opening curly bracket on the same line as the function declaration,
place the opening curly bracket on the same line as the function declaration,
with one space in between.
> At the time of writing, an automatic formatter, `rustfmt`, is under
@@ -127,45 +137,35 @@ This line does all of the work in this little program: it prints text to the
screen. There are a number of details to notice here. The first is that Rust
style is to indent with four spaces, not a tab.
The second important part is `println!`. This is calling a Rust *macro*, which
is how metaprogramming is done in Rust. If it were calling a function instead,
it would look like this: `println` (without the `!`). Well discuss Rust macros
in more detail in Appendix D, but for now you just need to know that when you
see a `!` that means that youre calling a macro instead of a normal function.
The second important detail is the `println!` call. This code is calling a Rust
*macro*. If it were calling a function instead, it would be entered as
`println` (without the `!`). Well discuss Rust macros in more detail in
Appendix D, but for now you just need to know that when you see a `!` that
means that youre calling a macro instead of a normal function.
> ### Why `println!` is a Macro
>
> There are multiple reasons why `println!` is a macro rather than a function,
> and we havent really explained Rust yet, so its not exactly obvious. Here
> are the reasons:
>
> * The string passed to `println!` can have formatting specifiers in it,
> and those are checked at compile-time.
> * Rust functions can only have a fixed number of arguments, but `println!`
> (and macros generally) can take a variable number.
> * The formatting specifiers can have named arguments, which Rust functions
> cannot.
> * It implicitly takes its arguments by reference even when theyre passed
> by value.
>
> If none of this makes sense, dont worry about it. Well cover these concepts
> in more detail later.
<!-- I might suggest just cutting this next macro section -- for the sake of
the intro, we don't really need this info, and I feel like this first exercise
should be short and sweet and simple -->
<!-- I'm ok with cutting this; it's a fairly common question that some folks
have at this point, but I'm ok with those people having to do some research
online if they're curious /Carol -->
Next is `"Hello, world!"` which is a *string*. We pass this string as an
argument to `println!`, which prints the string to the screen. Easy enough!
Next comes`"Hello, world!"` which is a *string*. We pass this string as an
argument to `println!` and the total effect is that the string is printed to
the screen. Easy enough!
The line ends with a semicolon (`;`). The `;` indicates that this expression is
We end the line with a semicolon `;`, which indicates that this expression is
over, and the next one is ready to begin. Most lines of Rust code end with a
`;`.
### Compiling and Running Are Separate Steps
In the “Writing and Running a Rust Program” section, we showed you how to run a
newly created program. Well break that process down and examine each step now.
Youve just seen how to run a newly created program, so now lets break that
process down and examine each step.
Before running a Rust program, you have to compile it. You can use the Rust
compiler by entering the `rustc` command and passing it the name of your source
file, like this:
Before running a Rust program, you have to compile it using the Rust compiler
by entering the `rustc` command and passing it the name of your source file,
like this:
```text
$ rustc main.rs
@@ -213,258 +213,6 @@ hand, they need to have a Ruby, Python, or JavaScript implementation installed
program. Everything is a tradeoff in language design.
Just compiling with `rustc` is fine for simple programs, but as your project
grows, youll want to be able to manage all of the options your project has and
make it easy to share your code with other people and projects. Next, well
introduce you to a tool called Cargo, which will help you write real-world Rust
programs.
## Hello, Cargo!
Cargo is Rusts build system and package manager, and Rustaceans use Cargo to
manage their Rust projects because it makes a lot of tasks easier. For example,
Cargo takes care of building your code, downloading the libraries your code
depends on, and building those libraries. We call libraries your code needs
*dependencies*.
The simplest Rust programs, like the one weve written so far, dont have any
dependencies, so right now, youd only be using the part of Cargo that can take
care of building your code. As you write more complex Rust programs, youll
want to add dependencies, and if you start off using Cargo, that will be a lot
easier to do.
As the vast majority of Rust projects use Cargo, we will assume that
youre using it for the rest of the book. Cargo comes installed with Rust
itself, if you used the official installers as covered in the “Installation”
section. If you installed Rust through some other means, you can check if you
have Cargo installed by typing the following into your terminal:
```text
$ cargo --version
```
If you see a version number, great! If you see an error like `command not
found`, then you should look at the documentation for your method of
installation to determine how to install Cargo separately.
### Creating a Project with Cargo
Lets create a new project using Cargo and look at how it differs from our
project in `hello_world`. Go back to your projects directory (or wherever you
decided to put your code):
Linux, Mac, and PowerShell:
```text
$ cd ~/projects
```
CMD for Windows:
```cmd
> cd \d "%USERPROFILE%\projects"
```
And then on any operating system run:
```text
$ cargo new hello_cargo --bin
$ cd hello_cargo
```
We passed the `--bin` argument to `cargo new` because our goal is to make an
executable application, as opposed to a library. Executables are binary
executable files often called just *binaries*. Weve given `hello_cargo` as the
name for our project, and Cargo creates its files in a directory of the same
name that we can then go into.
If we list the files in the *hello_cargo* directory, we can see that Cargo has
generated two files and one directory for us: a *Cargo.toml* and a *src*
directory with a *main.rs* file inside. It has also initialized a new git
repository in the *hello_cargo* directory for us, along with a *.gitignore*
file. Git is a common version control system. You can change `cargo new` to use
a different version control system, or no version control system, by using the
`--vcs` flag. Run `cargo new --help` to see the available options.
Open up *Cargo.toml* in your text editor of choice. It should look similar to
the code in Listing 1-2:
<span class="filename">Filename: Cargo.toml</span>
```toml
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
[dependencies]
```
<span class="caption">Listing 1-2: Contents of *Cargo.toml* generated by `cargo
new`</span>
This file is in the [*TOML*][toml]<!-- ignore --> (Toms Obvious, Minimal
Language) format. TOML is used as Cargos configuration format.
[toml]: https://github.com/toml-lang/toml
The first line, `[package]`, is a section heading that indicates that the
following statements are configuring a package. As we add more information to
this file, well add other sections.
The next three lines set the three bits of configuration that Cargo needs to
see in order to know that it should compile your program: its name, what
version it is, and who wrote it. Cargo gets your name and email information
from your environment. If its not correct, go ahead and fix that and save the
file.
The last line, `[dependencies]`, is the start of a section for you to list any
*crates* (which is what we call packages of Rust code) that your project will
depend on so that Cargo knows to download and compile those too. We wont need
any other crates for this project, but we will in the guessing game tutorial in
Chapter 2.
Now lets look at *src/main.rs*:
<span class="filename">Filename: src/main.rs</span>
```rust
fn main() {
println!("Hello, world!");
}
```
Cargo has generated a “Hello World!” for you, just like the one we wrote in
Listing 1-1! So that part is the same. The differences between our previous
project and the project generated by Cargo that weve seen so far are:
- Our code goes in the *src* directory
- The top level contains a *Cargo.toml* configuration file
Cargo expects your source files to live inside the *src* directory so that the
top-level project directory is just for READMEs, license information,
configuration files, and anything else not related to your code. In this way,
using Cargo helps you keep your projects nice and tidy. Theres a place for
everything, and everything is in its place.
If you started a project that doesnt use Cargo, as we did with our project in
the *hello_world* directory, you can convert it to a project that does use
Cargo by moving your code into the *src* directory and creating an appropriate
*Cargo.toml*.
### Building and Running a Cargo Project
Now lets look at whats different about building and running your Hello World
program through Cargo! To do so, enter the following commands:
```text
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
```
This creates an executable file in *target/debug/hello_cargo* (or
*target\\debug\\hello_cargo.exe* on Windows), which you can run with this
command:
```text
$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
Hello, world!
```
Bam! If all goes well, `Hello, world!` should print to the terminal once more.
Running `cargo build` for the first time also causes Cargo to create a new file
at the top level called *Cargo.lock*. Cargo uses *Cargo.lock* to keep track of
the exact versions of dependencies used to build your project. This project
doesnt have dependencies, so the file is a bit sparse. You wont ever need to
touch this file yourself; Cargo will manage its contents for you.
We just built a project with `cargo build` and ran it with
`./target/debug/hello_cargo`, but we can also use `cargo run` to compile and
then run:
```text
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
```
Notice that this time, we didnt see the output telling us that Cargo was
compiling `hello_cargo`. Cargo figured out that the files havent changed, so
it just ran the binary. If you had modified your source code, Cargo would have
rebuilt the project before running it, and you would have seen output like
this:
```text
$ cargo run
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
Running `target/debug/hello_cargo`
Hello, world!
```
Finally, theres `cargo check`. This will quickly check your code to make sure
that it compiles, but not bother producing an executable:
```text
$ cargo check
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
```
Why would you not want an executable? `cargo check` is often much faster than
`cargo build`, because Cargo can skip the entire step of producing the
executable. If were checking our work throughout the process of writing the
code, this will speed things up! As such, many Rustaceans run `cargo check` as
they write their program to make sure that it compiles, and then run `cargo
build` once theyre ready to give it a spin themselves.
So a few more differences weve now seen:
- Instead of using `rustc`, build a project using `cargo build` or
`cargo check` (or build and run it in one step with `cargo run`).
- Instead of the result of the build being put in the same directory as our
code, Cargo will put it in the *target/debug* directory.
The other advantage of using Cargo is that the commands are the same no matter
what operating system youre on, so at this point we will no longer be
providing specific instructions for Linux and Mac versus Windows.
### Building for Release
When your project is finally ready for release, you can use `cargo build
--release` to compile your project with optimizations. This will create an
executable in *target/release* instead of *target/debug*. These optimizations
make your Rust code run faster, but turning them on makes your program take
longer to compile. This is why there are two different profiles: one for
development when you want to be able to rebuild quickly and often, and one for
building the final program youll give to a user that wont be rebuilt and that
we want to run as fast as possible. If youre benchmarking the running time of
your code, be sure to run `cargo build --release` and benchmark with the
executable in *target/release*.
### Cargo as Convention
With simple projects, Cargo doesnt provide a whole lot of value over just
using `rustc`, but it will prove its worth as you continue. With complex
projects composed of multiple crates, its much easier to let Cargo coordinate
the build. With Cargo, you can just run `cargo build`, and it should work the
right way.
Even though the `hello_cargo` project is simple, it now uses much of the real
tooling youll use for the rest of your Rust career. In fact, you can get
started with virtually all Rust projects you want to work on with the following
commands to check out the code using Git, change into the project directory,
and build:
```text
$ git clone someurl.com/someproject
$ cd someproject
$ cargo build
```
If you want to look at Cargo in more detail, check out [its documentation],
which covers all of its features.
[its documentation]: https://doc.rust-lang.org/cargo/
grows, youll want to be able to manage all of the options and make it easy to
share your code. Next, well introduce you to a tool called Cargo, which will
help you write real-world Rust programs.

View File

@@ -0,0 +1,265 @@
## Hello, Cargo!
Cargo is Rusts build system and package manager. Most Rustaceans will use this
tool to manage their Rust projects because Cargo takes care of a lot of tasks
for you, such as building your code, downloading the libraries your code
depends on, and building those libraries. (We call libraries your code needs
*dependencies*.)
The simplest Rust programs, like the one weve written so far, dont have any
dependencies, so if we had built the Hello World project with Cargo, it would
only be using the part of Cargo that takes care of building your code. As you
write more complex Rust programs, youll want to add dependencies, and if you
start the project off using Cargo, that will be a lot easier to do.
As the vast majority of Rust projects use Cargo, the rest of this book will
assume that youre using Cargo too. Cargo comes installed with Rust itself, if
you used the official installers as covered in the “Installation” section. If
you installed Rust through some other means, you can check if you have Cargo
installed by entering the following into your terminal:
```text
$ cargo --version
```
If you see a version number, great! If you see an error like `command not
found`, then you should look at the documentation for your method of
installation to determine how to install Cargo separately.
### Creating a Project with Cargo
Lets create a new project using Cargo and look at how it differs from our
original Hello World project. Navigate back to your *projects* directory (or
wherever you decided to put your code) and then on any operating system run:
```text
$ cargo new hello_cargo --bin
$ cd hello_cargo
```
<!-- Below -- so we always have to start a cargo project with the --bin option
if we want it to be something we can execute and not just a library, is that
right? It might be worth laying that out -->
<!-- As of Rust 1.21.0 (the version we're using for the book), yes, you must
always specify `--bin`. In a version of Rust in the near future (1.25 or 1.26),
binary crates will become the default kind of crate that `cargo new` makes, so
you won't have to specify `--bin` (but you can if you want and the behavior
will be the same). We'd rather not go into any more detail than we have here
because of this change; I think "The `--bin` argument to passed to `cargo new`
makes an executable application (often just called a *binary*), as opposed to a
library." lays this out enough. /Carol -->
This creates a new binary executable called `hello_cargo`. The `--bin` argument
to passed to `cargo new` makes an executable application (often just called a
*binary*), as opposed to a library. Weve given `hello_cargo` as the name for
our project, and Cargo creates its files in a directory of the same name.
Go into the *hello_cargo* directory and list the files, and you should see that
Cargo has generated two files and one directory for us: a *Cargo.toml* and a
*src* directory with a *main.rs* file inside. It has also initialized a new git
repository, along with a *.gitignore* file.
> Note: Git is a common version control system. You can change `cargo new` to
> use a different version control system, or no version control system, by
> using the `--vcs` flag. Run `cargo new --help` to see the available options.
Open up *Cargo.toml* in your text editor of choice. It should look similar to
the code in Listing 1-2:
<span class="filename">Filename: Cargo.toml</span>
```toml
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
[dependencies]
```
<span class="caption">Listing 1-2: Contents of *Cargo.toml* generated by `cargo
new`</span>
This file is in the [*TOML*][toml]<!-- ignore --> (Toms Obvious, Minimal
Language) format, which is what Cargo uses as its configuration format.
[toml]: https://github.com/toml-lang/toml
The first line, `[package]`, is a section heading that indicates that the
following statements are configuring a package. As we add more information to
this file, well add other sections.
The next three lines set the configuration information Cargo needs in order to
know that it should compile your program: the name, the version, and who wrote
it. Cargo gets your name and email information from your environment, so if
thats not correct, go ahead and fix that and save the file.
The last line, `[dependencies]`, is the start of a section for you to list any
of your projects dependencies. In Rust, packages of code are referred to as
*crates*. We wont need any other crates for this project, but we will in the
first project in Chapter 2, so well use this dependencies section then.
Now open up *src/main.rs* and take a look:
<span class="filename">Filename: src/main.rs</span>
```rust
fn main() {
println!("Hello, world!");
}
```
Cargo has generated a “Hello World!” for you, just like the one we wrote in
Listing 1-1! So far, the differences between our previous project and the
project generated by Cargo are that with Cargo our code goes in the *src*
directory, and we have a *Cargo.toml* configuration file in the top directory.
Cargo expects your source files to live inside the *src* directory so that the
top-level project directory is just for READMEs, license information,
configuration files, and anything else not related to your code. In this way,
using Cargo helps you keep your projects nice and tidy. Theres a place for
everything, and everything is in its place.
If you started a project that doesnt use Cargo, as we did with our project in
the *hello_world* directory, you can convert it to a project that does use
Cargo by moving the project code into the *src* directory and creating an
appropriate *Cargo.toml*.
### Building and Running a Cargo Project
Now lets look at whats different about building and running your Hello World
program through Cargo! From your project directory, build your project by
entering the following commands:
```text
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
```
This creates an executable file in *target/debug/hello_cargo* (or
*target\\debug\\hello_cargo.exe* on Windows), which you can run with this
command:
```text
$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
Hello, world!
```
Bam! If all goes well, `Hello, world!` should print to the terminal once more.
Running `cargo build` for the first time also causes Cargo to create a new file
at the top level called *Cargo.lock*, which is used to keep track of the exact
versions of dependencies in your project. This project doesnt have
dependencies, so the file is a bit sparse. You wont ever need to touch this
file yourself; Cargo will manage its contents for you.
We just built a project with `cargo build` and ran it with
`./target/debug/hello_cargo`, but we can also use `cargo run` to compile and
then run all in one go:
```text
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
```
Notice that this time, we didnt see the output telling us that Cargo was
compiling `hello_cargo`. Cargo figured out that the files havent changed, so
it just ran the binary. If you had modified your source code, Cargo would have
rebuilt the project before running it, and you would have seen output like this:
```text
$ cargo run
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
Running `target/debug/hello_cargo`
Hello, world!
```
Finally, theres `cargo check`. This command will quickly check your code to
make sure that it compiles, but not bother producing an executable:
```text
$ cargo check
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
```
Why would you not want an executable? `cargo check` is often much faster than
`cargo build`, because it skips the entire step of producing the executable. If
youre checking your work throughout the process of writing the code, using
`cargo check` will speed things up! As such, many Rustaceans run `cargo check`
periodically as they write their program to make sure that it compiles, and
then run `cargo build` once theyre ready to give it a spin themselves.
So to recap, using Cargo:
- We can build a project using `cargo build` or `cargo check`
- We can build and run the project in one step with `cargo run`
- Instead of the result of the build being put in the same directory as our
code, Cargo will put it in the *target/debug* directory.
A final advantage of using Cargo is that the commands are the same no matter
what operating system youre on, so at this point we will no longer be
providing specific instructions for Linux and Mac versus Windows.
### Building for Release
When your project is finally ready for release, you can use `cargo build
--release` to compile your project with optimizations. This will create an
executable in *target/release* instead of *target/debug*. These optimizations
make your Rust code run faster, but turning them on makes your program take
longer to compile. This is why there are two different profiles: one for
development when you want to be able to rebuild quickly and often, and one for
building the final program youll give to a user that wont be rebuilt
repeatedly and that will run as fast as possible. If youre benchmarking the
running time of your code, be sure to run `cargo build --release` and benchmark
with the executable in *target/release*.
### Cargo as Convention
With simple projects, Cargo doesnt provide a whole lot of value over just
using `rustc`, but it will prove its worth as you continue. With complex
projects composed of multiple crates, its much easier to let Cargo coordinate
the build.
Even though the `hello_cargo` project is simple, it now uses much of the real
tooling youll use for the rest of your Rust career. In fact, to work on any
existing projects you can use the following commands to check out the code
using Git, change into the project directory, and build:
```text
$ git clone someurl.com/someproject
$ cd someproject
$ cargo build
```
If you want to look at Cargo in more detail, check out [its documentation].
[its documentation]: https://doc.rust-lang.org/cargo/
<!--Below -- I`m not sure this is the place for this conversation, it seems too
deep into the weeds for the "getting started" chapter. I know we discussed
Nightly Rust as an appendix previously, but honestly I think this is more
suited somewhere online, perhaps in the extended docs. I like the idea of
finishing the chapter here, on this practical note, and I think at this point
readers will want to get stuck in anyway and may skip this and never come back
because it's buried at the end of a chapter that's not really related to it. If
it's online somewhere separate they can come to it when they're ready. What do
you think?-->
<!-- Ok, I can see that. /Carol -->
## Summary
Youre already off to a great start on your Rust journey! In this chapter,
youve:
* Installed the latest stable version of Rust
* Written a “Hello, world!” program using both `rustc` directly and using
the conventions of `cargo`
This is a great time to build a more substantial program, to get used to
reading and writing Rust code. In the next chapter, well build a guessing game
program. If youd rather start by learning about how common programming
concepts work in Rust, see Chapter 3.