~liigo/tmp2/trunk

« back to all changes in this revision

Viewing changes to pot/intro.md.pot

  • Committer: Liigo Zhuang
  • Date: 2014-11-11 08:53:12 UTC
  • Revision ID: com.liigo@gmail.com-20141111085312-n022fut0s6vocd0i
add po templates dir

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# SOME DESCRIPTIVE TITLE
 
2
# Copyright (C) YEAR The Rust Project Developers
 
3
# This file is distributed under the same license as the Rust package.
 
4
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
 
5
#
 
6
#, fuzzy
 
7
msgid ""
 
8
msgstr ""
 
9
"Project-Id-Version: Rust 0.13.0\n"
 
10
"POT-Creation-Date: 2014-11-10 20:48+0800\n"
 
11
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 
12
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 
13
"Language-Team: LANGUAGE <LL@li.org>\n"
 
14
"Language: \n"
 
15
"MIME-Version: 1.0\n"
 
16
"Content-Type: text/plain; charset=UTF-8\n"
 
17
"Content-Transfer-Encoding: 8bit\n"
 
18
 
 
19
#. type: Plain text
 
20
#: src/doc/guide-crates.md:69 src/doc/intro.md:49
 
21
msgid "1 directory, 2 files ```"
 
22
msgstr ""
 
23
 
 
24
#. type: Plain text
 
25
#: src/doc/guide.md:1443 src/doc/intro.md:308 src/doc/intro.md:362
 
26
#, no-wrap
 
27
msgid ""
 
28
"    println!(\"{}\", x);\n"
 
29
"}\n"
 
30
"```\n"
 
31
msgstr ""
 
32
 
 
33
#. type: Plain text
 
34
#: src/doc/guide.md:1828 src/doc/intro.md:70
 
35
#, no-wrap
 
36
msgid ""
 
37
"```{rust}\n"
 
38
"fn main() {\n"
 
39
"    println!(\"Hello, world!\")\n"
 
40
"}\n"
 
41
"```\n"
 
42
msgstr ""
 
43
 
 
44
#. type: Plain text
 
45
#: src/doc/guide.md:3476 src/doc/intro.md:430
 
46
msgid "It gives us this error:"
 
47
msgstr ""
 
48
 
 
49
#. type: Plain text
 
50
#: src/doc/index.md:69 src/doc/intro.md:24
 
51
msgid "# Tools"
 
52
msgstr ""
 
53
 
 
54
#. type: Plain text
 
55
#: src/doc/intro.md:2
 
56
msgid "% A 30-minute Introduction to Rust"
 
57
msgstr ""
 
58
 
 
59
#. type: Plain text
 
60
#: src/doc/intro.md:5
 
61
msgid ""
 
62
"Rust is a modern systems programming language focusing on safety and speed. "
 
63
"It accomplishes these goals by being memory safe without using garbage "
 
64
"collection."
 
65
msgstr ""
 
66
 
 
67
#. type: Plain text
 
68
#: src/doc/intro.md:12
 
69
msgid ""
 
70
"This introduction will give you a rough idea of what Rust is like, eliding "
 
71
"many details. It does not require prior experience with systems programming, "
 
72
"but you may find the syntax easier if you've used a 'curly brace' "
 
73
"programming language before, like C or JavaScript. The concepts are more "
 
74
"important than the syntax, so don't worry if you don't get every last "
 
75
"detail: you can read [the Guide](guide.html) to get a more complete "
 
76
"explanation."
 
77
msgstr ""
 
78
 
 
79
#. type: Plain text
 
80
#: src/doc/intro.md:16
 
81
msgid ""
 
82
"Because this is about high-level concepts, you don't need to actually "
 
83
"install Rust to follow along. If you'd like to anyway, check out [the "
 
84
"homepage](http://rust-lang.org) for explanation."
 
85
msgstr ""
 
86
 
 
87
#. type: Plain text
 
88
#: src/doc/intro.md:22
 
89
msgid ""
 
90
"To show off Rust, let's talk about how easy it is to get started with Rust.  "
 
91
"Then, we'll talk about Rust's most interesting feature, **ownership**, and "
 
92
"then discuss how it makes concurrency easier to reason about. Finally, we'll "
 
93
"talk about how Rust breaks down the perceived dichotomy between speed and "
 
94
"safety."
 
95
msgstr ""
 
96
 
 
97
#. type: Plain text
 
98
#: src/doc/intro.md:27
 
99
msgid ""
 
100
"Getting started on a new Rust project is incredibly easy, thanks to Rust's "
 
101
"package manager, [Cargo](http://crates.io)."
 
102
msgstr ""
 
103
 
 
104
#. type: Plain text
 
105
#: src/doc/intro.md:29
 
106
msgid "To start a new project with Cargo, use `cargo new`:"
 
107
msgstr ""
 
108
 
 
109
#. type: Plain text
 
110
#: src/doc/intro.md:33
 
111
msgid "```{bash} $ cargo new hello_world --bin ```"
 
112
msgstr ""
 
113
 
 
114
#. type: Plain text
 
115
#: src/doc/intro.md:36
 
116
msgid ""
 
117
"We're passing `--bin` because we're making a binary program: if we were "
 
118
"making a library, we'd leave it off."
 
119
msgstr ""
 
120
 
 
121
#. type: Plain text
 
122
#: src/doc/intro.md:38
 
123
msgid "Let's check out what Cargo has generated for us:"
 
124
msgstr ""
 
125
 
 
126
#. type: Plain text
 
127
#: src/doc/intro.md:46
 
128
#, no-wrap
 
129
msgid ""
 
130
"```{bash}\n"
 
131
"$ cd hello_world\n"
 
132
"$ tree .\n"
 
133
".\n"
 
134
"├── Cargo.toml\n"
 
135
"└── src\n"
 
136
"    └── main.rs\n"
 
137
msgstr ""
 
138
 
 
139
#. type: Plain text
 
140
#: src/doc/intro.md:51
 
141
msgid ""
 
142
"This is all we need to get started. First, let's check out `Cargo.toml`:"
 
143
msgstr ""
 
144
 
 
145
#. type: Plain text
 
146
#: src/doc/intro.md:54 src/doc/intro.md:86
 
147
msgid "```{toml} [package]"
 
148
msgstr ""
 
149
 
 
150
#. type: Plain text
 
151
#: src/doc/intro.md:59
 
152
msgid ""
 
153
"name = \"hello_world\" version = \"0.0.1\" authors = [\"Your Name "
 
154
"<you@example.com>\"] ```"
 
155
msgstr ""
 
156
 
 
157
#. type: Plain text
 
158
#: src/doc/intro.md:62
 
159
msgid ""
 
160
"This is called a **manifest**, and it contains all of the metadata that "
 
161
"Cargo needs to compile your project."
 
162
msgstr ""
 
163
 
 
164
#. type: Plain text
 
165
#: src/doc/intro.md:64
 
166
msgid "Here's what's in `src/main.rs`:"
 
167
msgstr ""
 
168
 
 
169
#. type: Plain text
 
170
#: src/doc/intro.md:73
 
171
msgid ""
 
172
"Cargo generated a 'hello world' for us. We'll talk more about the syntax "
 
173
"here later, but that's what Rust code looks like! Let's compile and run it:"
 
174
msgstr ""
 
175
 
 
176
#. type: Plain text
 
177
#: src/doc/intro.md:80
 
178
#, no-wrap
 
179
msgid ""
 
180
"```{bash}\n"
 
181
"$ cargo run\n"
 
182
"   Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world)\n"
 
183
"     Running `target/hello_world`\n"
 
184
"Hello, world!\n"
 
185
"```\n"
 
186
msgstr ""
 
187
 
 
188
#. type: Plain text
 
189
#: src/doc/intro.md:83
 
190
msgid ""
 
191
"Using an external dependency in Rust is incredibly easy. You add a line to "
 
192
"your `Cargo.toml`:"
 
193
msgstr ""
 
194
 
 
195
#. type: Plain text
 
196
#: src/doc/intro.md:90
 
197
msgid ""
 
198
"name = \"hello_world\" version = \"0.0.1\" authors = [\"Your Name "
 
199
"<someone@example.com>\"]"
 
200
msgstr ""
 
201
 
 
202
#. type: Plain text
 
203
#: src/doc/intro.md:92
 
204
msgid "[dependencies.semver]"
 
205
msgstr ""
 
206
 
 
207
#. type: Plain text
 
208
#: src/doc/intro.md:95
 
209
msgid "git = \"https://github.com/rust-lang/semver.git\" ```"
 
210
msgstr ""
 
211
 
 
212
#. type: Plain text
 
213
#: src/doc/intro.md:98
 
214
msgid ""
 
215
"You added the `semver` library, which parses version numbers and compares "
 
216
"them according to the [SemVer specification](http://semver.org/)."
 
217
msgstr ""
 
218
 
 
219
#. type: Plain text
 
220
#: src/doc/intro.md:101
 
221
msgid "Now, you can pull in that library using `extern crate` in `main.rs`."
 
222
msgstr ""
 
223
 
 
224
#. type: Plain text
 
225
#: src/doc/intro.md:104
 
226
msgid "```{rust,ignore} extern crate semver;"
 
227
msgstr ""
 
228
 
 
229
#. type: Plain text
 
230
#: src/doc/intro.md:106
 
231
msgid "use semver::Version;"
 
232
msgstr ""
 
233
 
 
234
#. type: Plain text
 
235
#: src/doc/intro.md:115
 
236
#, no-wrap
 
237
msgid ""
 
238
"fn main() {\n"
 
239
"    assert!(Version::parse(\"1.2.3\") == Ok(Version {\n"
 
240
"        major: 1u,\n"
 
241
"        minor: 2u,\n"
 
242
"        patch: 3u,\n"
 
243
"        pre: vec!(),\n"
 
244
"        build: vec!(),\n"
 
245
"    }));\n"
 
246
msgstr ""
 
247
 
 
248
#. type: Plain text
 
249
#: src/doc/intro.md:119
 
250
#, no-wrap
 
251
msgid ""
 
252
"    println!(\"Versions compared successfully!\");\n"
 
253
"}\n"
 
254
"```\n"
 
255
msgstr ""
 
256
 
 
257
#. type: Plain text
 
258
#: src/doc/intro.md:122
 
259
msgid ""
 
260
"Again, we'll discuss the exact details of all of this syntax soon. For now, "
 
261
"let's compile and run it:"
 
262
msgstr ""
 
263
 
 
264
#. type: Plain text
 
265
#: src/doc/intro.md:131
 
266
#, no-wrap
 
267
msgid ""
 
268
"```{bash}\n"
 
269
"$ cargo run\n"
 
270
"    Updating git repository `https://github.com/rust-lang/semver.git`\n"
 
271
"   Compiling semver v0.0.1 (https://github.com/rust-lang/semver.git#bf739419)\n"
 
272
"   Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)\n"
 
273
"     Running `target/hello_world`\n"
 
274
"Versions compared successfully!\n"
 
275
"```\n"
 
276
msgstr ""
 
277
 
 
278
#. type: Plain text
 
279
#: src/doc/intro.md:137
 
280
msgid ""
 
281
"Because we only specified a repository without a version, if someone else "
 
282
"were to try out our project at a later date, when `semver` was updated, they "
 
283
"would get a different, possibly incompatible version. To solve this problem, "
 
284
"Cargo produces a file, `Cargo.lock`, which records the versions of any "
 
285
"dependencies.  This gives us repeatable builds."
 
286
msgstr ""
 
287
 
 
288
#. type: Plain text
 
289
#: src/doc/intro.md:144
 
290
msgid ""
 
291
"There is a lot more here, and this is a whirlwind tour, but you should feel "
 
292
"right at home if you've used tools like [Bundler](http://bundler.io/), [npm]"
 
293
"(https://www.npmjs.org/), or [pip](https://pip.pypa.io/en/latest/).  There's "
 
294
"no `Makefile`s or endless `autotools` output here. (Rust's tooling does "
 
295
"[play nice with external libraries written in those tools](http://crates.io/"
 
296
"native-build.html), if you need to.)"
 
297
msgstr ""
 
298
 
 
299
#. type: Plain text
 
300
#: src/doc/intro.md:146
 
301
msgid "Enough about tools, let's talk code!"
 
302
msgstr ""
 
303
 
 
304
#. type: Plain text
 
305
#: src/doc/intro.md:148
 
306
msgid "# Ownership"
 
307
msgstr ""
 
308
 
 
309
#. type: Plain text
 
310
#: src/doc/intro.md:156
 
311
msgid ""
 
312
"Rust's defining feature is 'memory safety without garbage collection.' Let's "
 
313
"take a moment to talk about what that means. **Memory safety** means that "
 
314
"the programming language eliminates certain kinds of bugs, such as [buffer "
 
315
"overflows](http://en.wikipedia.org/wiki/Buffer_overflow) and [dangling "
 
316
"pointers](http://en.wikipedia.org/wiki/Dangling_pointer). These problems "
 
317
"occur when you have unrestricted access to memory. As an example, here's "
 
318
"some Ruby code:"
 
319
msgstr ""
 
320
 
 
321
#. type: Plain text
 
322
#: src/doc/intro.md:159
 
323
msgid "```{ruby} v = [];"
 
324
msgstr ""
 
325
 
 
326
#. type: Plain text
 
327
#: src/doc/intro.md:161
 
328
msgid "v.push(\"Hello\");"
 
329
msgstr ""
 
330
 
 
331
#. type: Plain text
 
332
#: src/doc/intro.md:163
 
333
msgid "x = v[0];"
 
334
msgstr ""
 
335
 
 
336
#. type: Plain text
 
337
#: src/doc/intro.md:165
 
338
msgid "v.push(\"world\");"
 
339
msgstr ""
 
340
 
 
341
#. type: Plain text
 
342
#: src/doc/intro.md:168
 
343
msgid "puts x ```"
 
344
msgstr ""
 
345
 
 
346
#. type: Plain text
 
347
#: src/doc/intro.md:171
 
348
msgid ""
 
349
"We make an array, `v`, and then call `push` on it. `push` is a method which "
 
350
"adds an element to the end of an array."
 
351
msgstr ""
 
352
 
 
353
#. type: Plain text
 
354
#: src/doc/intro.md:174
 
355
msgid ""
 
356
"Next, we make a new variable, `x`, that's equal to the first element of the "
 
357
"array. Simple, but this is where the 'bug' will appear."
 
358
msgstr ""
 
359
 
 
360
#. type: Plain text
 
361
#: src/doc/intro.md:177
 
362
msgid ""
 
363
"Let's keep going. We then call `push` again, pushing \"world\" onto the end "
 
364
"of the array. `v` now is `[\"Hello\", \"world\"]`."
 
365
msgstr ""
 
366
 
 
367
#. type: Plain text
 
368
#: src/doc/intro.md:179
 
369
msgid "Finally, we print `x` with the `puts` method. This prints \"Hello.\""
 
370
msgstr ""
 
371
 
 
372
#. type: Plain text
 
373
#: src/doc/intro.md:181
 
374
msgid ""
 
375
"All good? Let's go over a similar, but subtly different example, in C++:"
 
376
msgstr ""
 
377
 
 
378
#. type: Plain text
 
379
#: src/doc/intro.md:186
 
380
msgid "```{cpp} #include<iostream> #include<vector> #include<string>"
 
381
msgstr ""
 
382
 
 
383
#. type: Plain text
 
384
#: src/doc/intro.md:189
 
385
#, no-wrap
 
386
msgid ""
 
387
"int main() {\n"
 
388
"    std::vector<std::string> v;\n"
 
389
msgstr ""
 
390
 
 
391
#. type: Plain text
 
392
#: src/doc/intro.md:191
 
393
#, no-wrap
 
394
msgid "    v.push_back(\"Hello\");\n"
 
395
msgstr ""
 
396
 
 
397
#. type: Plain text
 
398
#: src/doc/intro.md:193
 
399
#, no-wrap
 
400
msgid "    std::string& x = v[0];\n"
 
401
msgstr ""
 
402
 
 
403
#. type: Plain text
 
404
#: src/doc/intro.md:195
 
405
#, no-wrap
 
406
msgid "    v.push_back(\"world\");\n"
 
407
msgstr ""
 
408
 
 
409
#. type: Plain text
 
410
#: src/doc/intro.md:199
 
411
#, no-wrap
 
412
msgid ""
 
413
"    std::cout << x;\n"
 
414
"}\n"
 
415
"```\n"
 
416
msgstr ""
 
417
 
 
418
#. type: Plain text
 
419
#: src/doc/intro.md:204
 
420
msgid ""
 
421
"It's a little more verbose due to the static typing, but it's almost the "
 
422
"same thing. We make a `std::vector` of `std::string`s, we call `push_back` "
 
423
"(same as `push`) on it, take a reference to the first element of the vector, "
 
424
"call `push_back` again, and then print out the reference."
 
425
msgstr ""
 
426
 
 
427
#. type: Plain text
 
428
#: src/doc/intro.md:207
 
429
msgid ""
 
430
"There's two big differences here: one, they're not _exactly_ the same thing, "
 
431
"and two..."
 
432
msgstr ""
 
433
 
 
434
#. type: Plain text
 
435
#: src/doc/intro.md:213
 
436
msgid ""
 
437
"```{bash} $ g++ hello.cpp -Wall -Werror $ ./a.out Segmentation fault (core "
 
438
"dumped)  ```"
 
439
msgstr ""
 
440
 
 
441
#. type: Plain text
 
442
#: src/doc/intro.md:219
 
443
msgid ""
 
444
"A crash! (Note that this is actually system-dependent. Because referring to "
 
445
"an invalid reference is undefined behavior, the compiler can do anything, "
 
446
"including the right thing!) Even though we compiled with flags to give us as "
 
447
"many warnings as possible, and to treat those warnings as errors, we got no "
 
448
"errors. When we ran the program, it crashed."
 
449
msgstr ""
 
450
 
 
451
#. type: Plain text
 
452
#: src/doc/intro.md:224
 
453
msgid ""
 
454
"Why does this happen? When we append to an array, its length changes. Since "
 
455
"its length changes, we may need to allocate more memory. In Ruby, this "
 
456
"happens as well, we just don't think about it very often. So why does the C+"
 
457
"+ version segfault when we allocate more memory?"
 
458
msgstr ""
 
459
 
 
460
#. type: Plain text
 
461
#: src/doc/intro.md:231
 
462
msgid ""
 
463
"The answer is that in the C++ version, `x` is a **reference** to the memory "
 
464
"location where the first element of the array is stored. But in Ruby, `x` is "
 
465
"a standalone value, not connected to the underyling array at all. Let's dig "
 
466
"into the details for a moment. Your program has access to memory, provided "
 
467
"to it by the operating system. Each location in memory has an address.  So "
 
468
"when we make our vector, `v`, it's stored in a memory location somewhere:"
 
469
msgstr ""
 
470
 
 
471
#. type: Plain text
 
472
#: src/doc/intro.md:235
 
473
#, no-wrap
 
474
msgid ""
 
475
"| location | name | value |\n"
 
476
"|----------|------|-------|\n"
 
477
"| 0x30     | v    |       |\n"
 
478
msgstr ""
 
479
 
 
480
#. type: Plain text
 
481
#: src/doc/intro.md:239
 
482
msgid ""
 
483
"(Address numbers made up, and in hexadecimal. Those of you with deep C++ "
 
484
"knowledge, there are some simplifications going on here, like the lack of an "
 
485
"allocated length for the vector. This is an introduction.)"
 
486
msgstr ""
 
487
 
 
488
#. type: Plain text
 
489
#: src/doc/intro.md:242
 
490
msgid ""
 
491
"When we push our first string onto the array, we allocate some memory, and "
 
492
"`v` refers to it:"
 
493
msgstr ""
 
494
 
 
495
#. type: Plain text
 
496
#: src/doc/intro.md:247
 
497
#, no-wrap
 
498
msgid ""
 
499
"| location | name | value    |\n"
 
500
"|----------|------|----------|\n"
 
501
"| 0x30     | v    | 0x18     |\n"
 
502
"| 0x18     |      | \"Hello\"  |\n"
 
503
msgstr ""
 
504
 
 
505
#. type: Plain text
 
506
#: src/doc/intro.md:251
 
507
msgid ""
 
508
"We then make a reference to that first element. A reference is a variable "
 
509
"that points to a memory location, so its value is the memory location of the "
 
510
"`\"Hello\"` string:"
 
511
msgstr ""
 
512
 
 
513
#. type: Plain text
 
514
#: src/doc/intro.md:257
 
515
#, no-wrap
 
516
msgid ""
 
517
"| location | name | value    |\n"
 
518
"|----------|------|----------|\n"
 
519
"| 0x30     | v    | 0x18     |\n"
 
520
"| 0x18     |      | \"Hello\"  |\n"
 
521
"| 0x14     | x    | 0x18     |\n"
 
522
msgstr ""
 
523
 
 
524
#. type: Plain text
 
525
#: src/doc/intro.md:261
 
526
msgid ""
 
527
"When we push `\"world\"` onto the vector with `push_back`, there's no room: "
 
528
"we only allocated one element. So, we need to allocate two elements, copy "
 
529
"the `\"Hello\"` string over, and update the reference. Like this:"
 
530
msgstr ""
 
531
 
 
532
#. type: Plain text
 
533
#: src/doc/intro.md:269
 
534
#, no-wrap
 
535
msgid ""
 
536
"| location | name | value    |\n"
 
537
"|----------|------|----------|\n"
 
538
"| 0x30     | v    | 0x08     |\n"
 
539
"| 0x18     |      | GARBAGE  |\n"
 
540
"| 0x14     | x    | 0x18     |\n"
 
541
"| 0x08     |      | \"Hello\"  |\n"
 
542
"| 0x04     |      | \"world\"  |\n"
 
543
msgstr ""
 
544
 
 
545
#. type: Plain text
 
546
#: src/doc/intro.md:274
 
547
msgid ""
 
548
"Note that `v` now refers to the new list, which has two elements. It's all "
 
549
"good. But our `x` didn't get updated! It still points at the old location, "
 
550
"which isn't valid anymore. In fact, [the documentation for `push_back` "
 
551
"mentions this](http://en.cppreference.com/w/cpp/container/vector/push_back):"
 
552
msgstr ""
 
553
 
 
554
#. type: Plain text
 
555
#: src/doc/intro.md:277
 
556
msgid ""
 
557
"> If the new `size()` is greater than `capacity()` then all iterators and > "
 
558
"references (including the past-the-end iterator) are invalidated."
 
559
msgstr ""
 
560
 
 
561
#. type: Plain text
 
562
#: src/doc/intro.md:282
 
563
msgid ""
 
564
"Finding where these iterators and references are is a difficult problem, and "
 
565
"even in this simple case, `g++` can't help us here. While the bug is obvious "
 
566
"in this case, in real code, it can be difficult to track down the source of "
 
567
"the error."
 
568
msgstr ""
 
569
 
 
570
#. type: Plain text
 
571
#: src/doc/intro.md:291
 
572
msgid ""
 
573
"Before we talk about this solution, why didn't our Ruby code have this "
 
574
"problem? The semantics are a little more complicated, and explaining Ruby's "
 
575
"internals is out of the scope of a guide to Rust. But in a nutshell, Ruby's "
 
576
"garbage collector keeps track of references, and makes sure that everything "
 
577
"works as you might expect. This comes at an efficiency cost, and the "
 
578
"internals are more complex.  If you'd really like to dig into the details, "
 
579
"[this article](http://patshaughnessy.net/2012/1/18/seeing-double-how-ruby-"
 
580
"shares-string-values)  can give you more information."
 
581
msgstr ""
 
582
 
 
583
#. type: Plain text
 
584
#: src/doc/intro.md:294
 
585
msgid ""
 
586
"Garbage collection is a valid approach to memory safety, but Rust chooses a "
 
587
"different path.  Let's examine what the Rust version of this looks like:"
 
588
msgstr ""
 
589
 
 
590
#. type: Plain text
 
591
#: src/doc/intro.md:298
 
592
#, no-wrap
 
593
msgid ""
 
594
"```{rust,ignore}\n"
 
595
"fn main() {\n"
 
596
"    let mut v = vec![];\n"
 
597
msgstr ""
 
598
 
 
599
#. type: Plain text
 
600
#: src/doc/intro.md:300 src/doc/intro.md:354
 
601
#, no-wrap
 
602
msgid "    v.push(\"Hello\");\n"
 
603
msgstr ""
 
604
 
 
605
#. type: Plain text
 
606
#: src/doc/intro.md:302
 
607
#, no-wrap
 
608
msgid "    let x = &v[0];\n"
 
609
msgstr ""
 
610
 
 
611
#. type: Plain text
 
612
#: src/doc/intro.md:304 src/doc/intro.md:358
 
613
#, no-wrap
 
614
msgid "    v.push(\"world\");\n"
 
615
msgstr ""
 
616
 
 
617
#. type: Plain text
 
618
#: src/doc/intro.md:313
 
619
msgid ""
 
620
"This looks like a bit of both: fewer type annotations, but we do create new "
 
621
"variables with `let`. The method name is `push`, some other stuff is "
 
622
"different, but it's pretty close. So what happens when we compile this code? "
 
623
"Does Rust print `\"Hello\"`, or does Rust crash?"
 
624
msgstr ""
 
625
 
 
626
#. type: Plain text
 
627
#: src/doc/intro.md:315
 
628
msgid "Neither. It refuses to compile:"
 
629
msgstr ""
 
630
 
 
631
#. type: Plain text
 
632
#: src/doc/intro.md:332
 
633
#, no-wrap
 
634
msgid ""
 
635
"```{notrust,ignore}\n"
 
636
"$ cargo run\n"
 
637
"   Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world)\n"
 
638
"main.rs:8:5: 8:6 error: cannot borrow `v` as mutable because it is also borrowed as immutable\n"
 
639
"main.rs:8     v.push(\"world\");\n"
 
640
"              ^\n"
 
641
"main.rs:6:14: 6:15 note: previous borrow of `v` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `v` until the borrow ends\n"
 
642
"main.rs:6     let x = &v[0];\n"
 
643
"                       ^\n"
 
644
"main.rs:11:2: 11:2 note: previous borrow ends here\n"
 
645
"main.rs:1 fn main() {\n"
 
646
"...\n"
 
647
"main.rs:11 }\n"
 
648
"           ^\n"
 
649
"error: aborting due to previous error\n"
 
650
"```\n"
 
651
msgstr ""
 
652
 
 
653
#. type: Plain text
 
654
#: src/doc/intro.md:336
 
655
msgid ""
 
656
"When we try to mutate the array by `push`ing it the second time, Rust throws "
 
657
"an error. It says that we \"cannot borrow v as mutable because it is also "
 
658
"borrowed as immutable.\" What's up with \"borrowed\"?"
 
659
msgstr ""
 
660
 
 
661
#. type: Plain text
 
662
#: src/doc/intro.md:341
 
663
msgid ""
 
664
"In Rust, the type system encodes the notion of **ownership**. The variable "
 
665
"`v` is an \"owner\" of the vector. When we make a reference to `v`, we let "
 
666
"that variable (in this case, `x`) 'borrow' it for a while. Just like if you "
 
667
"own a book, and you lend it to me, I'm borrowing the book."
 
668
msgstr ""
 
669
 
 
670
#. type: Plain text
 
671
#: src/doc/intro.md:345
 
672
msgid ""
 
673
"So, when I try to modify the vector with the second call to `push`, I need "
 
674
"to be owning it. But `x` is borrowing it. You can't modify something that "
 
675
"you've lent to someone. And so Rust throws an error."
 
676
msgstr ""
 
677
 
 
678
#. type: Plain text
 
679
#: src/doc/intro.md:347
 
680
msgid "So how do we fix this problem? Well, we can make a copy of the element:"
 
681
msgstr ""
 
682
 
 
683
#. type: Plain text
 
684
#: src/doc/intro.md:352
 
685
#, no-wrap
 
686
msgid ""
 
687
"```{rust}\n"
 
688
"fn main() {\n"
 
689
"    let mut v = vec![];\n"
 
690
msgstr ""
 
691
 
 
692
#. type: Plain text
 
693
#: src/doc/intro.md:356
 
694
#, no-wrap
 
695
msgid "    let x = v[0].clone();\n"
 
696
msgstr ""
 
697
 
 
698
#. type: Plain text
 
699
#: src/doc/intro.md:366
 
700
msgid ""
 
701
"Note the addition of `clone()`. This creates a copy of the element, leaving "
 
702
"the original untouched. Now, we no longer have two references to the same "
 
703
"memory, and so the compiler is happy. Let's give that a try:"
 
704
msgstr ""
 
705
 
 
706
#. type: Plain text
 
707
#: src/doc/intro.md:373
 
708
#, no-wrap
 
709
msgid ""
 
710
"```{bash}\n"
 
711
"$ cargo run\n"
 
712
"   Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world)\n"
 
713
"     Running `target/hello_world`\n"
 
714
"Hello\n"
 
715
"```\n"
 
716
msgstr ""
 
717
 
 
718
#. type: Plain text
 
719
#: src/doc/intro.md:377
 
720
msgid ""
 
721
"Same result. Now, making a copy can be inefficient, so this solution may not "
 
722
"be acceptable. There are other ways to get around this problem, but this is "
 
723
"a toy example, and because we're in an introduction, we'll leave that for "
 
724
"later."
 
725
msgstr ""
 
726
 
 
727
#. type: Plain text
 
728
#: src/doc/intro.md:381
 
729
msgid ""
 
730
"The point is, the Rust compiler and its notion of ownership has saved us "
 
731
"from a bug that would crash the program. We've achieved safety, at compile "
 
732
"time, without needing to rely on a garbage collector to handle our memory."
 
733
msgstr ""
 
734
 
 
735
#. type: Plain text
 
736
#: src/doc/intro.md:383
 
737
msgid "# Concurrency"
 
738
msgstr ""
 
739
 
 
740
#. type: Plain text
 
741
#: src/doc/intro.md:388
 
742
msgid ""
 
743
"Rust's ownership model can help in other ways, as well. For example, take "
 
744
"concurrency. Concurrency is a big topic, and an important one for any modern "
 
745
"programming language. Let's take a look at how ownership can help you write "
 
746
"safe concurrent programs."
 
747
msgstr ""
 
748
 
 
749
#. type: Plain text
 
750
#: src/doc/intro.md:390
 
751
msgid "Here's an example of a concurrent Rust program:"
 
752
msgstr ""
 
753
 
 
754
#. type: Plain text
 
755
#: src/doc/intro.md:400
 
756
#, no-wrap
 
757
msgid ""
 
758
"```{rust}\n"
 
759
"fn main() {\n"
 
760
"    for _ in range(0u, 10u) {\n"
 
761
"        spawn(proc() {\n"
 
762
"            println!(\"Hello, world!\");\n"
 
763
"        });\n"
 
764
"    }\n"
 
765
"}\n"
 
766
"```\n"
 
767
msgstr ""
 
768
 
 
769
#. type: Plain text
 
770
#: src/doc/intro.md:405
 
771
msgid ""
 
772
"This program creates ten threads, who all print `Hello, world!`. The `spawn` "
 
773
"function takes one argument, a `proc`. 'proc' is short for 'procedure,' and "
 
774
"is a form of closure. This closure is executed in a new thread, created by "
 
775
"`spawn` itself."
 
776
msgstr ""
 
777
 
 
778
#. type: Plain text
 
779
#: src/doc/intro.md:414
 
780
msgid ""
 
781
"One common form of problem in concurrent programs is a 'data race.' This "
 
782
"occurs when two different threads attempt to access the same location in "
 
783
"memory in a non-synchronized way, where at least one of them is a write. If "
 
784
"one thread is attempting to read, and one thread is attempting to write, you "
 
785
"cannot be sure that your data will not be corrupted. Note the first half of "
 
786
"that requirement: two threads that attempt to access the same location in "
 
787
"memory. Rust's ownership model can track which pointers own which memory "
 
788
"locations, which solves this problem."
 
789
msgstr ""
 
790
 
 
791
#. type: Plain text
 
792
#: src/doc/intro.md:416
 
793
msgid "Let's see an example. This Rust code will not compile:"
 
794
msgstr ""
 
795
 
 
796
#. type: Plain text
 
797
#: src/doc/intro.md:420
 
798
#, no-wrap
 
799
msgid ""
 
800
"```{rust,ignore}\n"
 
801
"fn main() {\n"
 
802
"    let mut numbers = vec![1i, 2i, 3i];\n"
 
803
msgstr ""
 
804
 
 
805
#. type: Plain text
 
806
#: src/doc/intro.md:428
 
807
#, no-wrap
 
808
msgid ""
 
809
"    for i in range(0u, 3u) {\n"
 
810
"        spawn(proc() {\n"
 
811
"            for j in range(0, 3) { numbers[j] += 1 }\n"
 
812
"        });\n"
 
813
"    }\n"
 
814
"}\n"
 
815
"```\n"
 
816
msgstr ""
 
817
 
 
818
#. type: Plain text
 
819
#: src/doc/intro.md:443
 
820
#, no-wrap
 
821
msgid ""
 
822
"```{notrust,ignore}\n"
 
823
"6:71 error: capture of moved value: `numbers`\n"
 
824
"    for j in range(0, 3) { numbers[j] += 1 }\n"
 
825
"               ^~~~~~~\n"
 
826
"7:50 note: `numbers` moved into closure environment here because it has type `proc():Send`, which is non-copyable (perhaps you meant to use clone()?)\n"
 
827
"    spawn(proc() {\n"
 
828
"        for j in range(0, 3) { numbers[j] += 1 }\n"
 
829
"    });\n"
 
830
"6:79 error: cannot assign to immutable dereference (dereference is implicit, due to indexing)\n"
 
831
"        for j in range(0, 3) { numbers[j] += 1 }\n"
 
832
"                           ^~~~~~~~~~~~~~~\n"
 
833
"```\n"
 
834
msgstr ""
 
835
 
 
836
#. type: Plain text
 
837
#: src/doc/intro.md:449
 
838
msgid ""
 
839
"It mentions that \"numbers moved into closure environment\". Because we "
 
840
"referred to `numbers` inside of our `proc`, and we create three `proc`s, we "
 
841
"would have three references. Rust detects this and gives us the error: we "
 
842
"claim that `numbers` has ownership, but our code tries to make three owners. "
 
843
"This may cause a safety problem, so Rust disallows it."
 
844
msgstr ""
 
845
 
 
846
#. type: Plain text
 
847
#: src/doc/intro.md:460
 
848
msgid ""
 
849
"What to do here? Rust has two types that helps us: `Arc<T>` and `Mutex<T>`.  "
 
850
"\"Arc\" stands for \"atomically reference counted.\" In other words, an Arc "
 
851
"will keep track of the number of references to something, and not free the "
 
852
"associated resource until the count is zero. The 'atomic' portion refers to "
 
853
"an Arc's usage of concurrency primitives to atomically update the count, "
 
854
"making it safe across threads. If we use an Arc, we can have our three "
 
855
"references. But, an Arc does not allow mutable borrows of the data it holds, "
 
856
"and we want to modify what we're sharing. In this case, we can use a "
 
857
"`Mutex<T>` inside of our Arc. A Mutex will synchronize our accesses, so that "
 
858
"we can ensure that our mutation doesn't cause a data race."
 
859
msgstr ""
 
860
 
 
861
#. type: Plain text
 
862
#: src/doc/intro.md:462
 
863
msgid "Here's what using an Arc with a Mutex looks like:"
 
864
msgstr ""
 
865
 
 
866
#. type: Plain text
 
867
#: src/doc/intro.md:465
 
868
msgid "```{rust} use std::sync::{Arc,Mutex};"
 
869
msgstr ""
 
870
 
 
871
#. type: Plain text
 
872
#: src/doc/intro.md:468
 
873
#, no-wrap
 
874
msgid ""
 
875
"fn main() {\n"
 
876
"    let numbers = Arc::new(Mutex::new(vec![1i, 2i, 3i]));\n"
 
877
msgstr ""
 
878
 
 
879
#. type: Plain text
 
880
#: src/doc/intro.md:473
 
881
#, no-wrap
 
882
msgid ""
 
883
"    for i in range(0u, 3u) {\n"
 
884
"        let number = numbers.clone();\n"
 
885
"        spawn(proc() {\n"
 
886
"            let mut array = number.lock();\n"
 
887
msgstr ""
 
888
 
 
889
#. type: Plain text
 
890
#: src/doc/intro.md:475
 
891
#, no-wrap
 
892
msgid "            (*array)[i] += 1;\n"
 
893
msgstr ""
 
894
 
 
895
#. type: Plain text
 
896
#: src/doc/intro.md:481
 
897
#, no-wrap
 
898
msgid ""
 
899
"            println!(\"numbers[{}] is {}\", i, (*array)[i]);\n"
 
900
"        });\n"
 
901
"    }\n"
 
902
"}\n"
 
903
"```\n"
 
904
msgstr ""
 
905
 
 
906
#. type: Plain text
 
907
#: src/doc/intro.md:489
 
908
msgid ""
 
909
"We first have to `use` the appropriate library, and then we wrap our vector "
 
910
"in an Arc with the call to `Arc::new()`. Inside of the loop, we make a new "
 
911
"reference to the Arc with the `clone()` method. This will increment the "
 
912
"reference count. When each new `numbers` variable binding goes out of scope, "
 
913
"it will decrement the count. The `lock()` call will return us a reference to "
 
914
"the value inside the Mutex, and block any other calls to `lock()` until said "
 
915
"reference goes out of scope."
 
916
msgstr ""
 
917
 
 
918
#. type: Plain text
 
919
#: src/doc/intro.md:492
 
920
msgid ""
 
921
"We can compile and run this program without error, and in fact, see the non-"
 
922
"deterministic aspect:"
 
923
msgstr ""
 
924
 
 
925
#. type: Plain text
 
926
#: src/doc/intro.md:506
 
927
#, no-wrap
 
928
msgid ""
 
929
"```{shell}\n"
 
930
"$ cargo run\n"
 
931
"   Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world)\n"
 
932
"     Running `target/hello_world`\n"
 
933
"numbers[1] is 3\n"
 
934
"numbers[0] is 2\n"
 
935
"numbers[2] is 4\n"
 
936
"$ cargo run\n"
 
937
"     Running `target/hello_world`\n"
 
938
"numbers[2] is 4\n"
 
939
"numbers[1] is 3\n"
 
940
"numbers[0] is 2\n"
 
941
"```\n"
 
942
msgstr ""
 
943
 
 
944
#. type: Plain text
 
945
#: src/doc/intro.md:509
 
946
msgid ""
 
947
"Each time, we get a slightly different output, because each thread works in "
 
948
"a different order. You may not get the same output as this sample, even."
 
949
msgstr ""
 
950
 
 
951
#. type: Plain text
 
952
#: src/doc/intro.md:514
 
953
msgid ""
 
954
"The important part here is that the Rust compiler was able to use ownership "
 
955
"to give us assurance _at compile time_ that we weren't doing something "
 
956
"incorrect with regards to concurrency. In order to share ownership, we were "
 
957
"forced to be explicit and use a mechanism to ensure that it would be "
 
958
"properly handled."
 
959
msgstr ""
 
960
 
 
961
#. type: Plain text
 
962
#: src/doc/intro.md:516
 
963
msgid "# Safety _and_ speed"
 
964
msgstr ""
 
965
 
 
966
#. type: Plain text
 
967
#: src/doc/intro.md:522
 
968
msgid ""
 
969
"Safety and speed are always presented as a continuum. On one hand, you have "
 
970
"maximum speed, but no safety. On the other, you have absolute safety, with "
 
971
"no speed. Rust seeks to break out of this mode by introducing safety at "
 
972
"compile time, ensuring that you haven't done anything wrong, while compiling "
 
973
"to the same low-level code you'd expect without the safety."
 
974
msgstr ""
 
975
 
 
976
#. type: Plain text
 
977
#: src/doc/intro.md:525
 
978
msgid ""
 
979
"As an example, Rust's ownership system is _entirely_ at compile time. The "
 
980
"safety check that makes this an error about moved values:"
 
981
msgstr ""
 
982
 
 
983
#. type: Plain text
 
984
#: src/doc/intro.md:529
 
985
#, no-wrap
 
986
msgid ""
 
987
"```{rust,ignore}\n"
 
988
"fn main() {\n"
 
989
"    let vec = vec![1i, 2, 3];\n"
 
990
msgstr ""
 
991
 
 
992
#. type: Plain text
 
993
#: src/doc/intro.md:537
 
994
#, no-wrap
 
995
msgid ""
 
996
"    for i in range(1u, 3) {\n"
 
997
"        spawn(proc() {\n"
 
998
"            println!(\"{}\", vec[i]);\n"
 
999
"        });\n"
 
1000
"    }\n"
 
1001
"}\n"
 
1002
"```\n"
 
1003
msgstr ""
 
1004
 
 
1005
#. type: Plain text
 
1006
#: src/doc/intro.md:542
 
1007
msgid ""
 
1008
"carries no runtime penalty. And while some of Rust's safety features do have "
 
1009
"a run-time cost, there's often a way to write your code in such a way that "
 
1010
"you can remove it. As an example, this is a poor way to iterate through a "
 
1011
"vector:"
 
1012
msgstr ""
 
1013
 
 
1014
#. type: Plain text
 
1015
#: src/doc/intro.md:545 src/doc/intro.md:557
 
1016
msgid "```{rust} let vec = vec![1i, 2, 3];"
 
1017
msgstr ""
 
1018
 
 
1019
#. type: Plain text
 
1020
#: src/doc/intro.md:550
 
1021
#, no-wrap
 
1022
msgid ""
 
1023
"for i in range(1u, vec.len()) {\n"
 
1024
"     println!(\"{}\", vec[i]);\n"
 
1025
"}\n"
 
1026
"```\n"
 
1027
msgstr ""
 
1028
 
 
1029
#. type: Plain text
 
1030
#: src/doc/intro.md:554
 
1031
msgid ""
 
1032
"The reason is that the access of `vec[i]` does bounds checking, to ensure "
 
1033
"that we don't try to access an invalid index. However, we can remove this "
 
1034
"while retaining safety. The answer is iterators:"
 
1035
msgstr ""
 
1036
 
 
1037
#. type: Plain text
 
1038
#: src/doc/intro.md:562
 
1039
#, no-wrap
 
1040
msgid ""
 
1041
"for x in vec.iter() {\n"
 
1042
"    println!(\"{}\", x);\n"
 
1043
"}\n"
 
1044
"```\n"
 
1045
msgstr ""
 
1046
 
 
1047
#. type: Plain text
 
1048
#: src/doc/intro.md:566
 
1049
msgid ""
 
1050
"This version uses an iterator that yields each element of the vector in "
 
1051
"turn.  Because we have a reference to the element, rather than the whole "
 
1052
"vector itself, there's no array access bounds to check."
 
1053
msgstr ""
 
1054
 
 
1055
#. type: Plain text
 
1056
#: src/doc/intro.md:568
 
1057
msgid "# Learning More"
 
1058
msgstr ""
 
1059
 
 
1060
#. type: Plain text
 
1061
#: src/doc/intro.md:574
 
1062
msgid ""
 
1063
"I hope that this taste of Rust has given you an idea if Rust is the right "
 
1064
"language for you. We talked about Rust's tooling, how encoding ownership "
 
1065
"into the type system helps you find bugs, how Rust can help you write "
 
1066
"correct concurrent code, and how you don't have to pay a speed cost for much "
 
1067
"of this safety."
 
1068
msgstr ""
 
1069
 
 
1070
#. type: Plain text
 
1071
#: src/doc/intro.md:576
 
1072
msgid ""
 
1073
"To continue your Rustic education, read [the guide](guide.html) for a more "
 
1074
"in-depth exploration of Rust's syntax and concepts."
 
1075
msgstr ""