]> git.lizzy.rs Git - rust.git/blob - doc/po/ja/tutorial-borrowed-ptr.md.po
Update version numbers to 0.8
[rust.git] / doc / po / ja / tutorial-borrowed-ptr.md.po
1 # Japanese translations for Rust package
2 # Copyright (C) 2013 The Rust Project Developers
3 # This file is distributed under the same license as the Rust package.
4 # Automatically generated, 2013.
5 #
6 msgid ""
7 msgstr ""
8 "Project-Id-Version: Rust 0.8\n"
9 "POT-Creation-Date: 2013-07-22 23:37+0900\n"
10 "PO-Revision-Date: 2013-07-28 20:32+0900\n"
11 "Last-Translator: Automatically generated\n"
12 "Language-Team: none\n"
13 "Language: ja\n"
14 "MIME-Version: 1.0\n"
15 "Content-Type: text/plain; charset=UTF-8\n"
16 "Content-Transfer-Encoding: 8bit\n"
17 "Plural-Forms: nplurals=1; plural=0;\n"
18
19 #. type: Plain text
20 #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4
21 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4
22 #: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4
23 msgid "# Introduction"
24 msgstr "# イントロダクション"
25
26 #. type: Plain text
27 #: doc/tutorial.md:1108 doc/tutorial-borrowed-ptr.md:72
28 msgid "Now we can call `compute_distance()` in various ways:"
29 msgstr ""
30 "上記の `compute_distance()` 関数は、様々な方法で呼び出すことができます。"
31
32 #. type: Plain text
33 #: doc/tutorial-borrowed-ptr.md:2
34 msgid "% Rust Borrowed Pointers Tutorial"
35 msgstr ""
36
37 #. type: Plain text
38 #: doc/tutorial-borrowed-ptr.md:14
39 msgid ""
40 "Borrowed pointers are one of the more flexible and powerful tools available "
41 "in Rust. A borrowed pointer can point anywhere: into the managed or exchange "
42 "heap, into the stack, and even into the interior of another data structure. "
43 "A borrowed pointer is as flexible as a C pointer or C++ reference. However, "
44 "unlike C and C++ compilers, the Rust compiler includes special static checks "
45 "that ensure that programs use borrowed pointers safely. Another advantage of "
46 "borrowed pointers is that they are invisible to the garbage collector, so "
47 "working with borrowed pointers helps reduce the overhead of automatic memory "
48 "management."
49 msgstr ""
50
51 #. type: Plain text
52 #: doc/tutorial-borrowed-ptr.md:18
53 msgid ""
54 "Despite their complete safety, a borrowed pointer's representation at "
55 "runtime is the same as that of an ordinary pointer in a C program. They "
56 "introduce zero overhead. The compiler does all safety checks at compile time."
57 msgstr ""
58
59 #. type: Plain text
60 #: doc/tutorial-borrowed-ptr.md:24
61 msgid ""
62 "Although borrowed pointers have rather elaborate theoretical underpinnings "
63 "(region pointers), the core concepts will be familiar to anyone who has "
64 "worked with C or C++. Therefore, the best way to explain how they are used—"
65 "and their limitations—is probably just to work through several examples."
66 msgstr ""
67
68 #. type: Plain text
69 #: doc/tutorial-borrowed-ptr.md:26
70 msgid "# By example"
71 msgstr ""
72
73 #. type: Plain text
74 #: doc/tutorial-borrowed-ptr.md:31
75 msgid ""
76 "Borrowed pointers are called *borrowed* because they are only valid for a "
77 "limited duration. Borrowed pointers never claim any kind of ownership over "
78 "the data that they point to: instead, they are used for cases where you "
79 "would like to use data for a short time."
80 msgstr ""
81
82 #. type: Plain text
83 #: doc/tutorial-borrowed-ptr.md:33
84 msgid "As an example, consider a simple struct type `Point`:"
85 msgstr ""
86
87 #. type: Plain text
88 #: doc/tutorial-borrowed-ptr.md:37
89 msgid "~~~ struct Point {x: float, y: float} ~~~"
90 msgstr ""
91
92 #. type: Plain text
93 #: doc/tutorial-borrowed-ptr.md:41
94 msgid ""
95 "We can use this simple definition to allocate points in many different ways. "
96 "For example, in this code, each of these three local variables contains a "
97 "point, but allocated in a different place:"
98 msgstr ""
99
100 #. type: Plain text
101 #: doc/tutorial-borrowed-ptr.md:48
102 #, no-wrap
103 msgid ""
104 "~~~\n"
105 "# struct Point {x: float, y: float}\n"
106 "let on_the_stack :  Point =  Point {x: 3.0, y: 4.0};\n"
107 "let managed_box  : @Point = @Point {x: 5.0, y: 1.0};\n"
108 "let owned_box    : ~Point = ~Point {x: 7.0, y: 9.0};\n"
109 "~~~\n"
110 msgstr ""
111
112 #. type: Plain text
113 #: doc/tutorial-borrowed-ptr.md:60
114 msgid ""
115 "Suppose we wanted to write a procedure that computed the distance between "
116 "any two points, no matter where they were stored. For example, we might like "
117 "to compute the distance between `on_the_stack` and `managed_box`, or between "
118 "`managed_box` and `owned_box`. One option is to define a function that takes "
119 "two arguments of type `Point`—that is, it takes the points by value. But if "
120 "we define it this way, calling the function will cause the points to be "
121 "copied. For points, this is probably not so bad, but often copies are "
122 "expensive. Worse, if the data type contains mutable fields, copying can "
123 "change the semantics of your program in unexpected ways. So we'd like to "
124 "define a function that takes the points by pointer. We can use borrowed "
125 "pointers to do this:"
126 msgstr ""
127
128 #. type: Plain text
129 #: doc/tutorial-borrowed-ptr.md:70
130 #, no-wrap
131 msgid ""
132 "~~~\n"
133 "# struct Point {x: float, y: float}\n"
134 "# fn sqrt(f: float) -> float { 0f }\n"
135 "fn compute_distance(p1: &Point, p2: &Point) -> float {\n"
136 "    let x_d = p1.x - p2.x;\n"
137 "    let y_d = p1.y - p2.y;\n"
138 "    sqrt(x_d * x_d + y_d * y_d)\n"
139 "}\n"
140 "~~~\n"
141 msgstr ""
142
143 #. type: Plain text
144 #: doc/tutorial-borrowed-ptr.md:82
145 #, no-wrap
146 msgid ""
147 "~~~\n"
148 "# struct Point {x: float, y: float}\n"
149 "# let on_the_stack :  Point =  Point{x: 3.0, y: 4.0};\n"
150 "# let managed_box  : @Point = @Point{x: 5.0, y: 1.0};\n"
151 "# let owned_box    : ~Point = ~Point{x: 7.0, y: 9.0};\n"
152 "# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }\n"
153 "compute_distance(&on_the_stack, managed_box);\n"
154 "compute_distance(managed_box, owned_box);\n"
155 "~~~\n"
156 msgstr ""
157
158 #. type: Plain text
159 #: doc/tutorial-borrowed-ptr.md:89
160 msgid ""
161 "Here, the `&` operator takes the address of the variable `on_the_stack`; "
162 "this is because `on_the_stack` has the type `Point` (that is, a struct "
163 "value) and we have to take its address to get a value. We also call this "
164 "_borrowing_ the local variable `on_the_stack`, because we have created an "
165 "alias: that is, another name for the same data."
166 msgstr ""
167
168 #. type: Plain text
169 #: doc/tutorial-borrowed-ptr.md:95
170 msgid ""
171 "In contrast, we can pass the boxes `managed_box` and `owned_box` to "
172 "`compute_distance` directly. The compiler automatically converts a box like "
173 "`@Point` or `~Point` to a borrowed pointer like `&Point`. This is another "
174 "form of borrowing: in this case, the caller lends the contents of the "
175 "managed or owned box to the callee."
176 msgstr ""
177
178 #. type: Plain text
179 #: doc/tutorial-borrowed-ptr.md:105
180 msgid ""
181 "Whenever a caller lends data to a callee, there are some limitations on what "
182 "the caller can do with the original. For example, if the contents of a "
183 "variable have been lent out, you cannot send that variable to another task. "
184 "In addition, the compiler will reject any code that might cause the borrowed "
185 "value to be freed or overwrite its component fields with values of different "
186 "types (I'll get into what kinds of actions those are shortly). This rule "
187 "should make intuitive sense: you must wait for a borrower to return the "
188 "value that you lent it (that is, wait for the borrowed pointer to go out of "
189 "scope)  before you can make full use of it again."
190 msgstr ""
191
192 #. type: Plain text
193 #: doc/tutorial-borrowed-ptr.md:107
194 msgid "# Other uses for the & operator"
195 msgstr ""
196
197 #. type: Plain text
198 #: doc/tutorial-borrowed-ptr.md:109
199 msgid "In the previous example, the value `on_the_stack` was defined like so:"
200 msgstr ""
201
202 #. type: Plain text
203 #: doc/tutorial-borrowed-ptr.md:114
204 msgid ""
205 "~~~ # struct Point {x: float, y: float} let on_the_stack: Point = Point {x: "
206 "3.0, y: 4.0}; ~~~"
207 msgstr ""
208
209 #. type: Plain text
210 #: doc/tutorial-borrowed-ptr.md:119
211 msgid ""
212 "This declaration means that code can only pass `Point` by value to other "
213 "functions. As a consequence, we had to explicitly take the address of "
214 "`on_the_stack` to get a borrowed pointer. Sometimes however it is more "
215 "convenient to move the & operator into the definition of `on_the_stack`:"
216 msgstr ""
217
218 #. type: Plain text
219 #: doc/tutorial-borrowed-ptr.md:124
220 msgid ""
221 "~~~ # struct Point {x: float, y: float} let on_the_stack2: &Point = &Point "
222 "{x: 3.0, y: 4.0}; ~~~"
223 msgstr ""
224
225 #. type: Plain text
226 #: doc/tutorial-borrowed-ptr.md:128
227 msgid ""
228 "Applying `&` to an rvalue (non-assignable location) is just a convenient "
229 "shorthand for creating a temporary and taking its address. A more verbose "
230 "way to write the same code is:"
231 msgstr ""
232
233 #. type: Plain text
234 #: doc/tutorial-borrowed-ptr.md:134
235 msgid ""
236 "~~~ # struct Point {x: float, y: float} let tmp = Point {x: 3.0, y: 4.0}; "
237 "let on_the_stack2 : &Point = &tmp; ~~~"
238 msgstr ""
239
240 #. type: Plain text
241 #: doc/tutorial-borrowed-ptr.md:136
242 msgid "# Taking the address of fields"
243 msgstr ""
244
245 #. type: Plain text
246 #: doc/tutorial-borrowed-ptr.md:141
247 msgid ""
248 "As in C, the `&` operator is not limited to taking the address of local "
249 "variables. It can also take the address of fields or individual array "
250 "elements. For example, consider this type definition for `rectangle`:"
251 msgstr ""
252
253 #. type: Plain text
254 #: doc/tutorial-borrowed-ptr.md:147
255 msgid ""
256 "~~~ struct Point {x: float, y: float} // as before struct Size {w: float, h: "
257 "float} // as before struct Rectangle {origin: Point, size: Size} ~~~"
258 msgstr ""
259
260 #. type: Plain text
261 #: doc/tutorial-borrowed-ptr.md:149
262 msgid "Now, as before, we can define rectangles in a few different ways:"
263 msgstr ""
264
265 #. type: Plain text
266 #: doc/tutorial-borrowed-ptr.md:161
267 #, no-wrap
268 msgid ""
269 "~~~\n"
270 "# struct Point {x: float, y: float}\n"
271 "# struct Size {w: float, h: float} // as before\n"
272 "# struct Rectangle {origin: Point, size: Size}\n"
273 "let rect_stack   = &Rectangle {origin: Point {x: 1f, y: 2f},\n"
274 "                               size: Size {w: 3f, h: 4f}};\n"
275 "let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f},\n"
276 "                               size: Size {w: 3f, h: 4f}};\n"
277 "let rect_owned   = ~Rectangle {origin: Point {x: 5f, y: 6f},\n"
278 "                               size: Size {w: 3f, h: 4f}};\n"
279 "~~~\n"
280 msgstr ""
281
282 #. type: Plain text
283 #: doc/tutorial-borrowed-ptr.md:164
284 msgid ""
285 "In each case, we can extract out individual subcomponents with the `&` "
286 "operator. For example, I could write:"
287 msgstr ""
288
289 #. type: Plain text
290 #: doc/tutorial-borrowed-ptr.md:175
291 msgid ""
292 "~~~ # struct Point {x: float, y: float} // as before # struct Size {w: "
293 "float, h: float} // as before # struct Rectangle {origin: Point, size: Size} "
294 "# let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f}, size: Size {w: "
295 "3f, h: 4f}}; # let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f}, "
296 "size: Size {w: 3f, h: 4f}}; # let rect_owned = ~Rectangle {origin: Point {x: "
297 "5f, y: 6f}, size: Size {w: 3f, h: 4f}}; # fn compute_distance(p1: &Point, "
298 "p2: &Point) -> float { 0f } compute_distance(&rect_stack.origin, "
299 "&rect_managed.origin); ~~~"
300 msgstr ""
301
302 #. type: Plain text
303 #: doc/tutorial-borrowed-ptr.md:178
304 msgid ""
305 "which would borrow the field `origin` from the rectangle on the stack as "
306 "well as from the managed box, and then compute the distance between them."
307 msgstr ""
308
309 #. type: Plain text
310 #: doc/tutorial-borrowed-ptr.md:180
311 msgid "# Borrowing managed boxes and rooting"
312 msgstr ""
313
314 #. type: Plain text
315 #: doc/tutorial-borrowed-ptr.md:186
316 msgid ""
317 "We’ve seen a few examples so far of borrowing heap boxes, both managed and "
318 "owned. Up till this point, we’ve glossed over issues of safety. As stated in "
319 "the introduction, at runtime a borrowed pointer is simply a pointer, nothing "
320 "more. Therefore, avoiding C's problems with dangling pointers requires a "
321 "compile-time safety check."
322 msgstr ""
323
324 #. type: Plain text
325 #: doc/tutorial-borrowed-ptr.md:197
326 msgid ""
327 "The basis for the check is the notion of _lifetimes_. A lifetime is a static "
328 "approximation of the span of execution during which the pointer is valid: it "
329 "always corresponds to some expression or block within the program. Code "
330 "inside that expression can use the pointer without restrictions. But if the "
331 "pointer escapes from that expression (for example, if the expression "
332 "contains an assignment expression that assigns the pointer to a mutable "
333 "field of a data structure with a broader scope than the pointer itself), the "
334 "compiler reports an error. We'll be discussing lifetimes more in the "
335 "examples to come, and a more thorough introduction is also available."
336 msgstr ""
337
338 #. type: Plain text
339 #: doc/tutorial-borrowed-ptr.md:202
340 msgid ""
341 "When the `&` operator creates a borrowed pointer, the compiler must ensure "
342 "that the pointer remains valid for its entire lifetime. Sometimes this is "
343 "relatively easy, such as when taking the address of a local variable or a "
344 "field that is stored on the stack:"
345 msgstr ""
346
347 #. type: Plain text
348 #: doc/tutorial-borrowed-ptr.md:211
349 #, no-wrap
350 msgid ""
351 "~~~\n"
352 "struct X { f: int }\n"
353 "fn example1() {\n"
354 "    let mut x = X { f: 3 };\n"
355 "    let y = &mut x.f;  // -+ L\n"
356 "    ...                //  |\n"
357 "}                      // -+\n"
358 "~~~\n"
359 msgstr ""
360
361 #. type: Plain text
362 #: doc/tutorial-borrowed-ptr.md:216
363 msgid ""
364 "Here, the lifetime of the borrowed pointer `y` is simply L, the remainder of "
365 "the function body. The compiler need not do any other work to prove that "
366 "code will not free `x.f`. This is true even if the code mutates `x`."
367 msgstr ""
368
369 #. type: Plain text
370 #: doc/tutorial-borrowed-ptr.md:218
371 msgid "The situation gets more complex when borrowing data inside heap boxes:"
372 msgstr ""
373
374 #. type: Plain text
375 #: doc/tutorial-borrowed-ptr.md:227
376 #, no-wrap
377 msgid ""
378 "~~~\n"
379 "# struct X { f: int }\n"
380 "fn example2() {\n"
381 "    let mut x = @X { f: 3 };\n"
382 "    let y = &x.f;      // -+ L\n"
383 "    ...                //  |\n"
384 "}                      // -+\n"
385 "~~~\n"
386 msgstr ""
387
388 #. type: Plain text
389 #: doc/tutorial-borrowed-ptr.md:238
390 msgid ""
391 "In this example, the value `x` is a heap box, and `y` is therefore a pointer "
392 "into that heap box. Again the lifetime of `y` is L, the remainder of the "
393 "function body. But there is a crucial difference: suppose `x` were to be "
394 "reassigned during the lifetime L? If the compiler isn't careful, the managed "
395 "box could become *unrooted*, and would therefore be subject to garbage "
396 "collection. A heap box that is unrooted is one such that no pointer values "
397 "in the heap point to it. It would violate memory safety for the box that was "
398 "originally assigned to `x` to be garbage-collected, since a non-heap pointer "
399 "*`y`* still points into it."
400 msgstr ""
401
402 #. type: Plain text
403 #: doc/tutorial-borrowed-ptr.md:241
404 msgid ""
405 "> ***Note:*** Our current implementation implements the garbage collector > "
406 "using reference counting and cycle detection."
407 msgstr ""
408
409 #. type: Plain text
410 #: doc/tutorial-borrowed-ptr.md:247
411 msgid ""
412 "For this reason, whenever an `&` expression borrows the interior of a "
413 "managed box stored in a mutable location, the compiler inserts a temporary "
414 "that ensures that the managed box remains live for the entire lifetime. So, "
415 "the above example would be compiled as if it were written"
416 msgstr ""
417
418 #. type: Plain text
419 #: doc/tutorial-borrowed-ptr.md:257
420 #, no-wrap
421 msgid ""
422 "~~~\n"
423 "# struct X { f: int }\n"
424 "fn example2() {\n"
425 "    let mut x = @X {f: 3};\n"
426 "    let x1 = x;\n"
427 "    let y = &x1.f;     // -+ L\n"
428 "    ...                //  |\n"
429 "}                      // -+\n"
430 "~~~\n"
431 msgstr ""
432
433 #. type: Plain text
434 #: doc/tutorial-borrowed-ptr.md:260
435 msgid ""
436 "Now if `x` is reassigned, the pointer `y` will still remain valid. This "
437 "process is called *rooting*."
438 msgstr ""
439
440 #. type: Plain text
441 #: doc/tutorial-borrowed-ptr.md:262
442 msgid "# Borrowing owned boxes"
443 msgstr ""
444
445 #. type: Plain text
446 #: doc/tutorial-borrowed-ptr.md:268
447 msgid ""
448 "The previous example demonstrated *rooting*, the process by which the "
449 "compiler ensures that managed boxes remain live for the duration of a "
450 "borrow. Unfortunately, rooting does not work for borrows of owned boxes, "
451 "because it is not possible to have two references to a owned box."
452 msgstr ""
453
454 #. type: Plain text
455 #: doc/tutorial-borrowed-ptr.md:274
456 msgid ""
457 "For owned boxes, therefore, the compiler will only allow a borrow *if the "
458 "compiler can guarantee that the owned box will not be reassigned or moved "
459 "for the lifetime of the pointer*. This does not necessarily mean that the "
460 "owned box is stored in immutable memory. For example, the following function "
461 "is legal:"
462 msgstr ""
463
464 #. type: Plain text
465 #: doc/tutorial-borrowed-ptr.md:289
466 #, no-wrap
467 msgid ""
468 "~~~\n"
469 "# fn some_condition() -> bool { true }\n"
470 "# struct Foo { f: int }\n"
471 "fn example3() -> int {\n"
472 "    let mut x = ~Foo {f: 3};\n"
473 "    if some_condition() {\n"
474 "        let y = &x.f;      // -+ L\n"
475 "        return *y;         //  |\n"
476 "    }                      // -+\n"
477 "    x = ~Foo {f: 4};\n"
478 "    ...\n"
479 "# return 0;\n"
480 "}\n"
481 "~~~\n"
482 msgstr ""
483
484 #. type: Plain text
485 #: doc/tutorial-borrowed-ptr.md:295
486 msgid ""
487 "Here, as before, the interior of the variable `x` is being borrowed and `x` "
488 "is declared as mutable. However, the compiler can prove that `x` is not "
489 "assigned anywhere in the lifetime L of the variable `y`. Therefore, it "
490 "accepts the function, even though `x` is mutable and in fact is mutated "
491 "later in the function."
492 msgstr ""
493
494 #. type: Plain text
495 #: doc/tutorial-borrowed-ptr.md:301
496 msgid ""
497 "It may not be clear why we are so concerned about mutating a borrowed "
498 "variable. The reason is that the runtime system frees any owned box _as soon "
499 "as its owning reference changes or goes out of scope_. Therefore, a program "
500 "like this is illegal (and would be rejected by the compiler):"
501 msgstr ""
502
503 #. type: Plain text
504 #: doc/tutorial-borrowed-ptr.md:310
505 #, no-wrap
506 msgid ""
507 "~~~ {.xfail-test}\n"
508 "fn example3() -> int {\n"
509 "    let mut x = ~X {f: 3};\n"
510 "    let y = &x.f;\n"
511 "    x = ~X {f: 4};  // Error reported here.\n"
512 "    *y\n"
513 "}\n"
514 "~~~\n"
515 msgstr ""
516
517 #. type: Plain text
518 #: doc/tutorial-borrowed-ptr.md:313
519 msgid ""
520 "To make this clearer, consider this diagram showing the state of memory "
521 "immediately before the re-assignment of `x`:"
522 msgstr ""
523
524 #. type: Plain text
525 #: doc/tutorial-borrowed-ptr.md:316 doc/tutorial-borrowed-ptr.md:330
526 #, no-wrap
527 msgid ""
528 "~~~ {.notrust}\n"
529 "    Stack               Exchange Heap\n"
530 msgstr ""
531
532 #. type: Plain text
533 #: doc/tutorial-borrowed-ptr.md:325
534 #, no-wrap
535 msgid ""
536 "  x +----------+\n"
537 "    | ~{f:int} | ----+\n"
538 "  y +----------+     |\n"
539 "    | &int     | ----+\n"
540 "    +----------+     |    +---------+\n"
541 "                     +--> |  f: 3   |\n"
542 "                          +---------+\n"
543 "~~~\n"
544 msgstr ""
545
546 #. type: Plain text
547 #: doc/tutorial-borrowed-ptr.md:327
548 msgid "Once the reassignment occurs, the memory will look like this:"
549 msgstr ""
550
551 #. type: Plain text
552 #: doc/tutorial-borrowed-ptr.md:339
553 #, no-wrap
554 msgid ""
555 "  x +----------+          +---------+\n"
556 "    | ~{f:int} | -------> |  f: 4   |\n"
557 "  y +----------+          +---------+\n"
558 "    | &int     | ----+\n"
559 "    +----------+     |    +---------+\n"
560 "                     +--> | (freed) |\n"
561 "                          +---------+\n"
562 "~~~\n"
563 msgstr ""
564
565 #. type: Plain text
566 #: doc/tutorial-borrowed-ptr.md:342
567 msgid ""
568 "Here you can see that the variable `y` still points at the old box, which "
569 "has been freed."
570 msgstr ""
571
572 #. type: Plain text
573 #: doc/tutorial-borrowed-ptr.md:348
574 msgid ""
575 "In fact, the compiler can apply the same kind of reasoning to any memory "
576 "that is _(uniquely) owned by the stack frame_. So we could modify the "
577 "previous example to introduce additional owned pointers and structs, and the "
578 "compiler will still be able to detect possible mutations:"
579 msgstr ""
580
581 #. type: Plain text
582 #: doc/tutorial-borrowed-ptr.md:353
583 #, no-wrap
584 msgid ""
585 "~~~ {.xfail-test}\n"
586 "fn example3() -> int {\n"
587 "    struct R { g: int }\n"
588 "    struct S { f: ~R }\n"
589 msgstr ""
590
591 #. type: Plain text
592 #: doc/tutorial-borrowed-ptr.md:361
593 #, no-wrap
594 msgid ""
595 "    let mut x = ~S {f: ~R {g: 3}};\n"
596 "    let y = &x.f.g;\n"
597 "    x = ~S {f: ~R {g: 4}};  // Error reported here.\n"
598 "    x.f = ~R {g: 5};        // Error reported here.\n"
599 "    *y\n"
600 "}\n"
601 "~~~\n"
602 msgstr ""
603
604 #. type: Plain text
605 #: doc/tutorial-borrowed-ptr.md:365
606 msgid ""
607 "In this case, two errors are reported, one when the variable `x` is modified "
608 "and another when `x.f` is modified. Either modification would invalidate the "
609 "pointer `y`."
610 msgstr ""
611
612 #. type: Plain text
613 #: doc/tutorial-borrowed-ptr.md:367
614 msgid "# Borrowing and enums"
615 msgstr ""
616
617 #. type: Plain text
618 #: doc/tutorial-borrowed-ptr.md:373
619 msgid ""
620 "The previous example showed that the type system forbids any borrowing of "
621 "owned boxes found in aliasable, mutable memory. This restriction prevents "
622 "pointers from pointing into freed memory. There is one other case where the "
623 "compiler must be very careful to ensure that pointers remain valid: pointers "
624 "into the interior of an `enum`."
625 msgstr ""
626
627 #. type: Plain text
628 #: doc/tutorial-borrowed-ptr.md:376
629 msgid ""
630 "As an example, let’s look at the following `shape` type that can represent "
631 "both rectangles and circles:"
632 msgstr ""
633
634 #. type: Plain text
635 #: doc/tutorial-borrowed-ptr.md:385
636 #, no-wrap
637 msgid ""
638 "~~~\n"
639 "struct Point {x: float, y: float}; // as before\n"
640 "struct Size {w: float, h: float}; // as before\n"
641 "enum Shape {\n"
642 "    Circle(Point, float),   // origin, radius\n"
643 "    Rectangle(Point, Size)  // upper-left, dimensions\n"
644 "}\n"
645 "~~~\n"
646 msgstr ""
647
648 #. type: Plain text
649 #: doc/tutorial-borrowed-ptr.md:389
650 msgid ""
651 "Now we might write a function to compute the area of a shape. This function "
652 "takes a borrowed pointer to a shape, to avoid the need for copying."
653 msgstr ""
654
655 #. type: Plain text
656 #: doc/tutorial-borrowed-ptr.md:405
657 #, no-wrap
658 msgid ""
659 "~~~\n"
660 "# struct Point {x: float, y: float}; // as before\n"
661 "# struct Size {w: float, h: float}; // as before\n"
662 "# enum Shape {\n"
663 "#     Circle(Point, float),   // origin, radius\n"
664 "#     Rectangle(Point, Size)  // upper-left, dimensions\n"
665 "# }\n"
666 "# static tau: float = 6.28f;\n"
667 "fn compute_area(shape: &Shape) -> float {\n"
668 "    match *shape {\n"
669 "        Circle(_, radius) => 0.5 * tau * radius * radius,\n"
670 "        Rectangle(_, ref size) => size.w * size.h\n"
671 "    }\n"
672 "}\n"
673 "~~~\n"
674 msgstr ""
675
676 #. type: Plain text
677 #: doc/tutorial-borrowed-ptr.md:410
678 msgid ""
679 "The first case matches against circles. Here, the pattern extracts the "
680 "radius from the shape variant and the action uses it to compute the area of "
681 "the circle. (Like any up-to-date engineer, we use the [tau circle constant]"
682 "[tau] and not that dreadfully outdated notion of pi)."
683 msgstr ""
684
685 #. type: Plain text
686 #: doc/tutorial-borrowed-ptr.md:412
687 msgid "[tau]: http://www.math.utah.edu/~palais/pi.html"
688 msgstr ""
689
690 #. type: Plain text
691 #: doc/tutorial-borrowed-ptr.md:418
692 msgid ""
693 "The second match is more interesting. Here we match against a rectangle and "
694 "extract its size: but rather than copy the `size` struct, we use a by-"
695 "reference binding to create a pointer to it. In other words, a pattern "
696 "binding like `ref size` binds the name `size` to a pointer of type `&size` "
697 "into the _interior of the enum_."
698 msgstr ""
699
700 #. type: Plain text
701 #: doc/tutorial-borrowed-ptr.md:421
702 msgid ""
703 "To make this more clear, let's look at a diagram of memory layout in the "
704 "case where `shape` points at a rectangle:"
705 msgstr ""
706
707 #. type: Plain text
708 #: doc/tutorial-borrowed-ptr.md:424 doc/tutorial-borrowed-ptr.md:449
709 #, no-wrap
710 msgid ""
711 "~~~ {.notrust}\n"
712 "Stack             Memory\n"
713 msgstr ""
714
715 #. type: Plain text
716 #: doc/tutorial-borrowed-ptr.md:433
717 #, no-wrap
718 msgid ""
719 "+-------+         +---------------+\n"
720 "| shape | ------> | rectangle(    |\n"
721 "+-------+         |   {x: float,  |\n"
722 "| size  | -+      |    y: float}, |\n"
723 "+-------+  +----> |   {w: float,  |\n"
724 "                  |    h: float}) |\n"
725 "                  +---------------+\n"
726 "~~~\n"
727 msgstr ""
728
729 #. type: Plain text
730 #: doc/tutorial-borrowed-ptr.md:440
731 msgid ""
732 "Here you can see that rectangular shapes are composed of five words of "
733 "memory. The first is a tag indicating which variant this enum is "
734 "(`rectangle`, in this case). The next two words are the `x` and `y` fields "
735 "for the point and the remaining two are the `w` and `h` fields for the size. "
736 "The binding `size` is then a pointer into the inside of the shape."
737 msgstr ""
738
739 #. type: Plain text
740 #: doc/tutorial-borrowed-ptr.md:446
741 msgid ""
742 "Perhaps you can see where the danger lies: if the shape were somehow to be "
743 "reassigned, perhaps to a circle, then although the memory used to store that "
744 "shape value would still be valid, _it would have a different type_! The "
745 "following diagram shows what memory would look like if code overwrote "
746 "`shape` with a circle:"
747 msgstr ""
748
749 #. type: Plain text
750 #: doc/tutorial-borrowed-ptr.md:458
751 #, no-wrap
752 msgid ""
753 "+-------+         +---------------+\n"
754 "| shape | ------> | circle(       |\n"
755 "+-------+         |   {x: float,  |\n"
756 "| size  | -+      |    y: float}, |\n"
757 "+-------+  +----> |   float)      |\n"
758 "                  |               |\n"
759 "                  +---------------+\n"
760 "~~~\n"
761 msgstr ""
762
763 #. type: Plain text
764 #: doc/tutorial-borrowed-ptr.md:463
765 msgid ""
766 "As you can see, the `size` pointer would be pointing at a `float` instead of "
767 "a struct. This is not good: dereferencing the second field of a `float` as "
768 "if it were a struct with two fields would be a memory safety violation."
769 msgstr ""
770
771 #. type: Plain text
772 #: doc/tutorial-borrowed-ptr.md:475
773 msgid ""
774 "So, in fact, for every `ref` binding, the compiler will impose the same "
775 "rules as the ones we saw for borrowing the interior of a owned box: it must "
776 "be able to guarantee that the `enum` will not be overwritten for the "
777 "duration of the borrow.  In fact, the compiler would accept the example we "
778 "gave earlier. The example is safe because the shape pointer has type "
779 "`&Shape`, which means \"borrowed pointer to immutable memory containing a "
780 "`shape`\". If, however, the type of that pointer were `&mut Shape`, then the "
781 "ref binding would be ill-typed.  Just as with owned boxes, the compiler will "
782 "permit `ref` bindings into data owned by the stack frame even if the data "
783 "are mutable, but otherwise it requires that the data reside in immutable "
784 "memory."
785 msgstr ""
786
787 #. type: Plain text
788 #: doc/tutorial-borrowed-ptr.md:477
789 msgid "# Returning borrowed pointers"
790 msgstr ""
791
792 #. type: Plain text
793 #: doc/tutorial-borrowed-ptr.md:483
794 msgid ""
795 "So far, all of the examples we have looked at, use borrowed pointers in a "
796 "“downward” direction. That is, a method or code block creates a borrowed "
797 "pointer, then uses it within the same scope. It is also possible to return "
798 "borrowed pointers as the result of a function, but as we'll see, doing so "
799 "requires some explicit annotation."
800 msgstr ""
801
802 #. type: Plain text
803 #: doc/tutorial-borrowed-ptr.md:485
804 msgid "For example, we could write a subroutine like this:"
805 msgstr ""
806
807 #. type: Plain text
808 #: doc/tutorial-borrowed-ptr.md:490
809 msgid ""
810 "~~~ struct Point {x: float, y: float} fn get_x<'r>(p: &'r Point) -> &'r "
811 "float { &p.x } ~~~"
812 msgstr ""
813
814 #. type: Plain text
815 #: doc/tutorial-borrowed-ptr.md:498
816 msgid ""
817 "Here, the function `get_x()` returns a pointer into the structure it was "
818 "given. The type of the parameter (`&'r Point`) and return type (`&'r float`) "
819 "both use a new syntactic form that we have not seen so far.  Here the "
820 "identifier `r` names the lifetime of the pointer explicitly. So in effect, "
821 "this function declares that it takes a pointer with lifetime `r` and returns "
822 "a pointer with that same lifetime."
823 msgstr ""
824
825 #. type: Plain text
826 #: doc/tutorial-borrowed-ptr.md:504
827 msgid ""
828 "In general, it is only possible to return borrowed pointers if they are "
829 "derived from a parameter to the procedure. In that case, the pointer result "
830 "will always have the same lifetime as one of the parameters; named lifetimes "
831 "indicate which parameter that is."
832 msgstr ""
833
834 #. type: Plain text
835 #: doc/tutorial-borrowed-ptr.md:510
836 msgid ""
837 "In the previous examples, function parameter types did not include a "
838 "lifetime name. In those examples, the compiler simply creates a fresh name "
839 "for the lifetime automatically: that is, the lifetime name is guaranteed to "
840 "refer to a distinct lifetime from the lifetimes of all other parameters."
841 msgstr ""
842
843 #. type: Plain text
844 #: doc/tutorial-borrowed-ptr.md:518
845 msgid ""
846 "Named lifetimes that appear in function signatures are conceptually the same "
847 "as the other lifetimes we have seen before, but they are a bit abstract: "
848 "they don’t refer to a specific expression within `get_x()`, but rather to "
849 "some expression within the *caller of `get_x()`*.  The lifetime `r` is "
850 "actually a kind of *lifetime parameter*: it is defined by the caller to "
851 "`get_x()`, just as the value for the parameter `p` is defined by that caller."
852 msgstr ""
853
854 #. type: Plain text
855 #: doc/tutorial-borrowed-ptr.md:523
856 msgid ""
857 "In any case, whatever the lifetime of `r` is, the pointer produced by `&p.x` "
858 "always has the same lifetime as `p` itself: a pointer to a field of a struct "
859 "is valid as long as the struct is valid. Therefore, the compiler accepts the "
860 "function `get_x()`."
861 msgstr ""
862
863 #. type: Plain text
864 #: doc/tutorial-borrowed-ptr.md:526
865 msgid ""
866 "To emphasize this point, let’s look at a variation on the example, this time "
867 "one that does not compile:"
868 msgstr ""
869
870 #. type: Plain text
871 #: doc/tutorial-borrowed-ptr.md:533
872 #, no-wrap
873 msgid ""
874 "~~~ {.xfail-test}\n"
875 "struct Point {x: float, y: float}\n"
876 "fn get_x_sh(p: @Point) -> &float {\n"
877 "    &p.x // Error reported here\n"
878 "}\n"
879 "~~~\n"
880 msgstr ""
881
882 #. type: Plain text
883 #: doc/tutorial-borrowed-ptr.md:541
884 msgid ""
885 "Here, the function `get_x_sh()` takes a managed box as input and returns a "
886 "borrowed pointer. As before, the lifetime of the borrowed pointer that will "
887 "be returned is a parameter (specified by the caller). That means that "
888 "`get_x_sh()` promises to return a borrowed pointer that is valid for as long "
889 "as the caller would like: this is subtly different from the first example, "
890 "which promised to return a pointer that was valid for as long as its pointer "
891 "argument was valid."
892 msgstr ""
893
894 #. type: Plain text
895 #: doc/tutorial-borrowed-ptr.md:552
896 msgid ""
897 "Within `get_x_sh()`, we see the expression `&p.x` which takes the address of "
898 "a field of a managed box. The presence of this expression implies that the "
899 "compiler must guarantee that, so long as the resulting pointer is valid, the "
900 "managed box will not be reclaimed by the garbage collector. But recall that "
901 "`get_x_sh()` also promised to return a pointer that was valid for as long as "
902 "the caller wanted it to be. Clearly, `get_x_sh()` is not in a position to "
903 "make both of these guarantees; in fact, it cannot guarantee that the pointer "
904 "will remain valid at all once it returns, as the parameter `p` may or may "
905 "not be live in the caller. Therefore, the compiler will report an error here."
906 msgstr ""
907
908 #. type: Plain text
909 #: doc/tutorial-borrowed-ptr.md:559
910 msgid ""
911 "In general, if you borrow a managed (or owned) box to create a borrowed "
912 "pointer, the pointer will only be valid within the function and cannot be "
913 "returned. This is why the typical way to return borrowed pointers is to take "
914 "borrowed pointers as input (the only other case in which it can be legal to "
915 "return a borrowed pointer is if the pointer points at a static constant)."
916 msgstr ""
917
918 #. type: Plain text
919 #: doc/tutorial-borrowed-ptr.md:561
920 msgid "# Named lifetimes"
921 msgstr ""
922
923 #. type: Plain text
924 #: doc/tutorial-borrowed-ptr.md:565
925 msgid ""
926 "Let's look at named lifetimes in more detail. Named lifetimes allow for "
927 "grouping of parameters by lifetime. For example, consider this function:"
928 msgstr ""
929
930 #. type: Plain text
931 #: doc/tutorial-borrowed-ptr.md:579
932 #, no-wrap
933 msgid ""
934 "~~~\n"
935 "# struct Point {x: float, y: float}; // as before\n"
936 "# struct Size {w: float, h: float}; // as before\n"
937 "# enum Shape {\n"
938 "#     Circle(Point, float),   // origin, radius\n"
939 "#     Rectangle(Point, Size)  // upper-left, dimensions\n"
940 "# }\n"
941 "# fn compute_area(shape: &Shape) -> float { 0f }\n"
942 "fn select<'r, T>(shape: &'r Shape, threshold: float,\n"
943 "                 a: &'r T, b: &'r T) -> &'r T {\n"
944 "    if compute_area(shape) > threshold {a} else {b}\n"
945 "}\n"
946 "~~~\n"
947 msgstr ""
948
949 #. type: Plain text
950 #: doc/tutorial-borrowed-ptr.md:585
951 msgid ""
952 "This function takes three borrowed pointers and assigns each the same "
953 "lifetime `r`.  In practice, this means that, in the caller, the lifetime `r` "
954 "will be the *intersection of the lifetime of the three region parameters*. "
955 "This may be overly conservative, as in this example:"
956 msgstr ""
957
958 #. type: Plain text
959 #: doc/tutorial-borrowed-ptr.md:607
960 #, no-wrap
961 msgid ""
962 "~~~\n"
963 "# struct Point {x: float, y: float}; // as before\n"
964 "# struct Size {w: float, h: float}; // as before\n"
965 "# enum Shape {\n"
966 "#     Circle(Point, float),   // origin, radius\n"
967 "#     Rectangle(Point, Size)  // upper-left, dimensions\n"
968 "# }\n"
969 "# fn compute_area(shape: &Shape) -> float { 0f }\n"
970 "# fn select<'r, T>(shape: &Shape, threshold: float,\n"
971 "#                  a: &'r T, b: &'r T) -> &'r T {\n"
972 "#     if compute_area(shape) > threshold {a} else {b}\n"
973 "# }\n"
974 "                                                     // -+ r\n"
975 "fn select_based_on_unit_circle<'r, T>(               //  |-+ B\n"
976 "    threshold: float, a: &'r T, b: &'r T) -> &'r T { //  | |\n"
977 "                                                     //  | |\n"
978 "    let shape = Circle(Point {x: 0., y: 0.}, 1.);    //  | |\n"
979 "    select(&shape, threshold, a, b)                  //  | |\n"
980 "}                                                    //  |-+\n"
981 "                                                     // -+\n"
982 "~~~\n"
983 msgstr ""
984
985 #. type: Plain text
986 #: doc/tutorial-borrowed-ptr.md:617
987 msgid ""
988 "In this call to `select()`, the lifetime of the first parameter shape is B, "
989 "the function body. Both of the second two parameters `a` and `b` share the "
990 "same lifetime, `r`, which is a lifetime parameter of "
991 "`select_based_on_unit_circle()`. The caller will infer the intersection of "
992 "these two lifetimes as the lifetime of the returned value, and hence the "
993 "return value of `select()` will be assigned a lifetime of B. This will in "
994 "turn lead to a compilation error, because `select_based_on_unit_circle()` is "
995 "supposed to return a value with the lifetime `r`."
996 msgstr ""
997
998 #. type: Plain text
999 #: doc/tutorial-borrowed-ptr.md:622
1000 msgid ""
1001 "To address this, we can modify the definition of `select()` to distinguish "
1002 "the lifetime of the first parameter from the lifetime of the latter two. "
1003 "After all, the first parameter is not being returned. Here is how the new "
1004 "`select()` might look:"
1005 msgstr ""
1006
1007 #. type: Plain text
1008 #: doc/tutorial-borrowed-ptr.md:636
1009 #, no-wrap
1010 msgid ""
1011 "~~~\n"
1012 "# struct Point {x: float, y: float}; // as before\n"
1013 "# struct Size {w: float, h: float}; // as before\n"
1014 "# enum Shape {\n"
1015 "#     Circle(Point, float),   // origin, radius\n"
1016 "#     Rectangle(Point, Size)  // upper-left, dimensions\n"
1017 "# }\n"
1018 "# fn compute_area(shape: &Shape) -> float { 0f }\n"
1019 "fn select<'r, 'tmp, T>(shape: &'tmp Shape, threshold: float,\n"
1020 "                       a: &'r T, b: &'r T) -> &'r T {\n"
1021 "    if compute_area(shape) > threshold {a} else {b}\n"
1022 "}\n"
1023 "~~~\n"
1024 msgstr ""
1025
1026 #. type: Plain text
1027 #: doc/tutorial-borrowed-ptr.md:641
1028 msgid ""
1029 "Here you can see that `shape`'s lifetime is now named `tmp`. The parameters "
1030 "`a`, `b`, and the return value all have the lifetime `r`.  However, since "
1031 "the lifetime `tmp` is not returned, it would be more concise to just omit "
1032 "the named lifetime for `shape` altogether:"
1033 msgstr ""
1034
1035 #. type: Plain text
1036 #: doc/tutorial-borrowed-ptr.md:655
1037 #, no-wrap
1038 msgid ""
1039 "~~~\n"
1040 "# struct Point {x: float, y: float}; // as before\n"
1041 "# struct Size {w: float, h: float}; // as before\n"
1042 "# enum Shape {\n"
1043 "#     Circle(Point, float),   // origin, radius\n"
1044 "#     Rectangle(Point, Size)  // upper-left, dimensions\n"
1045 "# }\n"
1046 "# fn compute_area(shape: &Shape) -> float { 0f }\n"
1047 "fn select<'r, T>(shape: &Shape, threshold: float,\n"
1048 "                 a: &'r T, b: &'r T) -> &'r T {\n"
1049 "    if compute_area(shape) > threshold {a} else {b}\n"
1050 "}\n"
1051 "~~~\n"
1052 msgstr ""
1053
1054 #. type: Plain text
1055 #: doc/tutorial-borrowed-ptr.md:657
1056 msgid "This is equivalent to the previous definition."
1057 msgstr ""
1058
1059 #. type: Plain text
1060 #: doc/tutorial-borrowed-ptr.md:659
1061 msgid "# Conclusion"
1062 msgstr ""
1063
1064 #. type: Plain text
1065 #: doc/tutorial-borrowed-ptr.md:663
1066 msgid ""
1067 "So there you have it: a (relatively) brief tour of the borrowed pointer "
1068 "system. For more details, we refer to the (yet to be written) reference "
1069 "document on borrowed pointers, which will explain the full notation and give "
1070 "more examples."
1071 msgstr ""