]> git.proxmox.com Git - rustc.git/blame - src/doc/book/second-edition/src/ch01-02-hello-world.md
New upstream version 1.22.1+dfsg1
[rustc.git] / src / doc / book / second-edition / src / ch01-02-hello-world.md
CommitLineData
cc61c64b
XL
1## Hello, World!
2
3b2f2976 3Now that you have Rust installed, let’s write your first Rust program. It’s
cc61c64b 4traditional when learning a new language to write a little program to print the
3b2f2976 5text “Hello, world!” to the screen, and in this section, we’ll follow that
cc61c64b
XL
6tradition.
7
8> Note: This book assumes basic familiarity with the command line. Rust itself
9> makes no specific demands about your editing, tooling, or where your code
10> lives, so if you prefer an IDE to the command line, feel free to use your
11> favorite IDE.
12
13### Creating a Project Directory
14
3b2f2976
XL
15First, make a directory to put your Rust code in. Rust doesn’t care where your code
16lives, but for this book, we’d suggest making a *projects* directory in your
cc61c64b
XL
17home directory and keeping all your projects there. Open a terminal and enter
18the following commands to make a directory for this particular project:
19
20Linux and Mac:
21
22```text
23$ mkdir ~/projects
24$ cd ~/projects
25$ mkdir hello_world
26$ cd hello_world
27```
28
7cac9316 29Windows CMD:
cc61c64b
XL
30
31```cmd
32> mkdir %USERPROFILE%\projects
33> cd %USERPROFILE%\projects
34> mkdir hello_world
35> cd hello_world
36```
37
7cac9316
XL
38Windows PowerShell:
39
40```powershell
41> mkdir $env:USERPROFILE\projects
42> cd $env:USERPROFILE\projects
43> mkdir hello_world
44> cd hello_world
45```
46
cc61c64b
XL
47### Writing and Running a Rust Program
48
49Next, make a new source file and call it *main.rs*. Rust files always end with
50the *.rs* extension. If you’re using more than one word in your filename, use
3b2f2976 51an underscore to separate them. For example, you’d use *hello_world.rs* rather
cc61c64b
XL
52than *helloworld.rs*.
53
54Now open the *main.rs* file you just created, and type the following code:
55
56<span class="filename">Filename: main.rs</span>
57
58```rust
59fn main() {
60 println!("Hello, world!");
61}
62```
63
64Save the file, and go back to your terminal window. On Linux or OSX, enter the
65following commands:
66
67```text
68$ rustc main.rs
69$ ./main
70Hello, world!
71```
72
73On Windows, run `.\main.exe` instead of `./main`. Regardless of your
74operating system, you should see the string `Hello, world!` print to the
3b2f2976 75terminal. If you did, then congratulations! You’ve officially written a Rust
7cac9316 76program. That makes you a Rust programmer! Welcome!
cc61c64b
XL
77
78### Anatomy of a Rust Program
79
3b2f2976
XL
80Now, let’s go over what just happened in your “Hello, world!” program in
81detail. Here’s the first piece of the puzzle:
cc61c64b
XL
82
83```rust
84fn main() {
85
86}
87```
88
3b2f2976 89These lines define a *function* in Rust. The `main` function is special: it’s
cc61c64b
XL
90the first thing that is run for every executable Rust program. The first line
91says, “I’m declaring a function named `main` that has no parameters and returns
92nothing.” If there were parameters, their names would go inside the
93parentheses, `(` and `)`.
94
ea8adc8c
XL
95Also note that the function body is wrapped in curly brackets, `{` and `}`.
96Rust requires these around all function bodies. It’s considered good style to
97put the opening curly bracket on the same line as the function declaration,
98with one space in between.
cc61c64b
XL
99
100Inside the `main` function:
101
102```rust
103 println!("Hello, world!");
104```
105
106This line does all of the work in this little program: it prints text to the
107screen. There are a number of details to notice here. The first is that Rust
108style is to indent with four spaces, not a tab.
109
110The second important part is `println!`. This is calling a Rust *macro*,
111which is how metaprogramming is done in Rust. If it were calling a function
3b2f2976 112instead, it would look like this: `println` (without the `!`). We’ll discuss
cc61c64b
XL
113Rust macros in more detail in Appendix E, but for now you just need to know
114that when you see a `!` that means that you’re calling a macro instead of a
115normal function.
116
117Next is `"Hello, world!"` which is a *string*. We pass this string as an
118argument to `println!`, which prints the string to the screen. Easy enough!
119
120The line ends with a semicolon (`;`). The `;` indicates that this expression is
121over, and the next one is ready to begin. Most lines of Rust code end with a
122`;`.
123
124### Compiling and Running Are Separate Steps
125
3b2f2976
XL
126In “Writing and Running a Rust Program”, we showed you how to run a newly
127created program. We’ll break that process down and examine each step now.
cc61c64b
XL
128
129Before running a Rust program, you have to compile it. You can use the Rust
130compiler by entering the `rustc` command and passing it the name of your source
131file, like this:
132
133```text
134$ rustc main.rs
135```
136
3b2f2976 137If you come from a C or C++ background, you’ll notice that this is similar to
cc61c64b
XL
138`gcc` or `clang`. After compiling successfully, Rust should output a binary
139executable, which you can see on Linux or OSX by entering the `ls` command in
140your shell as follows:
141
142```text
143$ ls
144main main.rs
145```
146
3b2f2976 147On Windows, you’d enter:
cc61c64b
XL
148
149```cmd
150> dir /B %= the /B option says to only show the file names =%
151main.exe
152main.rs
153```
154
155This shows we have two files: the source code, with the *.rs* extension, and the
3b2f2976 156executable (*main.exe* on Windows, *main* everywhere else). All that’s left to
cc61c64b
XL
157do from here is run the *main* or *main.exe* file, like this:
158
159```text
160$ ./main # or .\main.exe on Windows
161```
162
3b2f2976 163If *main.rs* were your “Hello, world!” program, this would print `Hello,
cc61c64b
XL
164world!` to your terminal.
165
166If you come from a dynamic language like Ruby, Python, or JavaScript, you may
167not be used to compiling and running a program being separate steps. Rust is an
168*ahead-of-time compiled* language, which means that you can compile a program,
169give it to someone else, and they can run it even without having Rust
170installed. If you give someone a `.rb`, `.py`, or `.js` file, on the other
171hand, they need to have a Ruby, Python, or JavaScript implementation installed
172(respectively), but you only need one command to both compile and run your
173program. Everything is a tradeoff in language design.
174
175Just compiling with `rustc` is fine for simple programs, but as your project
3b2f2976
XL
176grows, you’ll want to be able to manage all of the options your project has
177and make it easy to share your code with other people and projects. Next, we’ll
cc61c64b
XL
178introduce you to a tool called Cargo, which will help you write real-world Rust
179programs.
180
181## Hello, Cargo!
182
183Cargo is Rust’s build system and package manager, and Rustaceans use Cargo to
184manage their Rust projects because it makes a lot of tasks easier. For example,
185Cargo takes care of building your code, downloading the libraries your code
186depends on, and building those libraries. We call libraries your code needs
187*dependencies*.
188
3b2f2976
XL
189The simplest Rust programs, like the one we’ve written so far, don’t have any
190dependencies, so right now, you’d only be using the part of Cargo that can take
cc61c64b
XL
191care of building your code. As you write more complex Rust programs, you’ll
192want to add dependencies, and if you start off using Cargo, that will be a lot
193easier to do.
194
195As the vast, vast majority of Rust projects use Cargo, we will assume that
196you’re using it for the rest of the book. Cargo comes installed with Rust
197itself, if you used the official installers as covered in the Installation
198chapter. If you installed Rust through some other means, you can check if you
199have Cargo installed by typing the following into your terminal:
200
201```text
202$ cargo --version
203```
204
205If you see a version number, great! If you see an error like `command not
206found`, then you should look at the documentation for your method of
207installation to determine how to install Cargo separately.
208
209### Creating a Project with Cargo
210
3b2f2976 211Let’s create a new project using Cargo and look at how it differs from our
cc61c64b
XL
212project in `hello_world`. Go back to your projects directory (or wherever you
213decided to put your code):
214
215Linux and Mac:
216
217```text
218$ cd ~/projects
219```
220
221Windows:
222
223```cmd
224> cd %USERPROFILE%\projects
225```
226
227And then on any operating system run:
228
229```text
230$ cargo new hello_cargo --bin
231$ cd hello_cargo
232```
233
234We passed the `--bin` argument to `cargo new` because our goal is to make an
235executable application, as opposed to a library. Executables are binary
3b2f2976 236executable files often called just *binaries*. We’ve given `hello_cargo`
cc61c64b
XL
237as the name for our project, and Cargo creates its files in a directory
238of the same name that we can then go into.
239
240If we list the files in the *hello_cargo* directory, we can see that Cargo has
241generated two files and one directory for us: a *Cargo.toml* and a *src*
242directory with a *main.rs* file inside. It has also initialized a new git
243repository in the *hello_cargo* directory for us, along with a *.gitignore*
244file; you can change this to use a different version control system, or no
245version control system, by using the `--vcs` flag.
246
247Open up *Cargo.toml* in your text editor of choice. It should look something
248like this:
249
250<span class="filename">Filename: Cargo.toml</span>
251
252```toml
253[package]
254name = "hello_cargo"
255version = "0.1.0"
256authors = ["Your Name <you@example.com>"]
257
258[dependencies]
259```
260
3b2f2976 261This file is in the [*TOML*][toml]<!-- ignore --> (Tom’s Obvious, Minimal
cc61c64b
XL
262Language) format. TOML is similar to INI but has some extra goodies and is used
263as Cargo’s configuration format.
264
265[toml]: https://github.com/toml-lang/toml
266
267The first line, `[package]`, is a section heading that indicates that the
268following statements are configuring a package. As we add more information to
269this file, we’ll add other sections.
270
271The next three lines set the three bits of configuration that Cargo needs to
272see in order to know that it should compile your program: its name, what
273version it is, and who wrote it. Cargo gets your name and email information
274from your environment. If it’s not correct, go ahead and fix that and save the
275file.
276
277The last line, `[dependencies]`, is the start of a section for you to list any
278*crates* (which is what we call packages of Rust code) that your project will
3b2f2976 279depend on so that Cargo knows to download and compile those too. We won’t need
cc61c64b
XL
280any other crates for this project, but we will in the guessing game tutorial in
281the next chapter.
282
3b2f2976 283Now let’s look at *src/main.rs*:
cc61c64b
XL
284
285<span class="filename">Filename: src/main.rs</span>
286
287```rust
288fn main() {
289 println!("Hello, world!");
290}
291```
292
3b2f2976 293Cargo has generated a “Hello World!” for you, just like the one we wrote
cc61c64b 294earlier! So that part is the same. The differences between our previous project
3b2f2976 295and the project generated by Cargo that we’ve seen so far are:
cc61c64b
XL
296
297- Our code goes in the *src* directory
298- The top level contains a *Cargo.toml* configuration file
299
300Cargo expects your source files to live inside the *src* directory so that the
301top-level project directory is just for READMEs, license information,
302configuration files, and anything else not related to your code. In this way,
3b2f2976 303using Cargo helps you keep your projects nice and tidy. There’s a place for
cc61c64b
XL
304everything, and everything is in its place.
305
3b2f2976 306If you started a project that doesn’t use Cargo, as we did with our project in
cc61c64b
XL
307the *hello_world* directory, you can convert it to a project that does use
308Cargo by moving your code into the *src* directory and creating an appropriate
309*Cargo.toml*.
310
311### Building and Running a Cargo Project
312
3b2f2976 313Now let’s look at what’s different about building and running your Hello World
cc61c64b
XL
314program through Cargo! To do so, enter the following commands:
315
316```text
317$ cargo build
318 Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
319```
320
321This should have created an executable file in *target/debug/hello_cargo* (or
ea8adc8c 322*target\\debug\\hello_cargo.exe* on Windows), which you can run with this command:
cc61c64b
XL
323
324```text
325$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
326Hello, world!
327```
328
329Bam! If all goes well, `Hello, world!` should print to the terminal once more.
330
331Running `cargo build` for the first time also causes Cargo to create a new file
332at the top level called *Cargo.lock*, which looks like this:
333
334<span class="filename">Filename: Cargo.lock</span>
335
336```toml
337[root]
338name = "hello_cargo"
339version = "0.1.0"
340```
341
342Cargo uses the *Cargo.lock* to keep track of dependencies in your application.
3b2f2976
XL
343This project doesn’t have dependencies, so the file is a bit sparse.
344Realistically, you won’t ever need to touch this file yourself; just let Cargo
cc61c64b
XL
345handle it.
346
347We just built a project with `cargo build` and ran it with
348`./target/debug/hello_cargo`, but we can also use `cargo run` to compile
349and then run:
350
351```text
352$ cargo run
353 Running `target/debug/hello_cargo`
354Hello, world!
355```
356
3b2f2976 357Notice that this time, we didn’t see the output telling us that Cargo was
cc61c64b
XL
358compiling `hello_cargo`. Cargo figured out that the files haven’t changed, so
359it just ran the binary. If you had modified your source code, Cargo would have
360rebuilt the project before running it, and you would have seen something like
361this:
362
363```text
364$ cargo run
365 Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
366 Running `target/debug/hello_cargo`
367Hello, world!
368```
369
3b2f2976 370So a few more differences we’ve now seen:
cc61c64b
XL
371
372- Instead of using `rustc`, build a project using `cargo build` (or build and
373 run it in one step with `cargo run`)
374- Instead of the result of the build being put in the same directory as our
375 code, Cargo will put it in the *target/debug* directory.
376
377The other advantage of using Cargo is that the commands are the same no matter
3b2f2976 378what operating system you’re on, so at this point we will no longer be
cc61c64b
XL
379providing specific instructions for Linux and Mac versus Windows.
380
381### Building for Release
382
383When your project is finally ready for release, you can use `cargo build
384--release` to compile your project with optimizations. This will create an
385executable in *target/release* instead of *target/debug*. These optimizations
386make your Rust code run faster, but turning them on makes your program take
387longer to compile. This is why there are two different profiles: one for
388development when you want to be able to rebuild quickly and often, and one for
3b2f2976
XL
389building the final program you’ll give to a user that won’t be rebuilt and
390that we want to run as fast as possible. If you’re benchmarking the running
cc61c64b
XL
391time of your code, be sure to run `cargo build --release` and benchmark with
392the executable in *target/release*.
393
394### Cargo as Convention
395
3b2f2976 396With simple projects, Cargo doesn’t provide a whole lot of value over just
cc61c64b
XL
397using `rustc`, but it will prove its worth as you continue. With complex
398projects composed of multiple crates, it’s much easier to let Cargo coordinate
399the build. With Cargo, you can just run `cargo build`, and it should work the
400right way. Even though this project is simple, it now uses much of the real
401tooling you’ll use for the rest of your Rust career. In fact, you can get
402started with virtually all Rust projects you want to work
403on with the following commands:
404
405```text
406$ git clone someurl.com/someproject
407$ cd someproject
408$ cargo build
409```
410
411> Note: If you want to look at Cargo in more detail, check out the official
412[Cargo guide], which covers all of its features.
413
414[Cargo guide]: http://doc.crates.io/guide.html