@@ -3466,13 +3466,14 @@ for destroying that resource as well. Given that we're discussing pointers
3466
3466
right now, let's discuss this in the context of memory allocation, though
3467
3467
it applies to other resources as well.
3468
3468
3469
- When you allocate heap memory, you need a mechanism to free that memory. Many
3470
- languages let the programmer control the allocation, and then use a garbage
3471
- collector to handle the deallocation. This is a valid, time-tested strategy,
3472
- but it's not without its drawbacks. Because the programmer does not have to
3473
- think as much about deallocation, allocation becomes something commonplace,
3474
- because it's easy. And if you need precise control over when something is
3475
- deallocated, leaving it up to your runtime can make this difficult.
3469
+ When you allocate heap memory, you need a mechanism to free that memory. Many
3470
+ languages use a garbage collector to handle deallocation. This is a valid,
3471
+ time-tested strategy, but it's not without its drawbacks: it adds overhead, and
3472
+ can lead to unpredictable pauses in execution. Because the programmer does not
3473
+ have to think as much about deallocation, allocation becomes something
3474
+ commonplace, leading to more memory usage. And if you need precise control
3475
+ over when something is deallocated, leaving it up to your runtime can make this
3476
+ difficult.
3476
3477
3477
3478
Rust chooses a different path, and that path is called ** ownership** . Any
3478
3479
binding that creates a resource is the ** owner** of that resource.
@@ -3498,17 +3499,19 @@ memory. The length of time that the borrower is borrowing the pointer
3498
3499
from you is called a ** lifetime** .
3499
3500
3500
3501
If two distinct bindings share a pointer, and the memory that pointer points to
3501
- is immutable, then there are no problems. But if it's mutable, both pointers
3502
- can attempt to write to the memory at the same time, causing a ** race
3503
- condition** . Therefore, if someone wants to mutate something that they've
3504
- borrowed from you, you must not have lent out that pointer to anyone else.
3502
+ is immutable, then there are no problems. But if it's mutable, the result of
3503
+ changing it can vary unpredictably depending on who happens to access it first,
3504
+ which is called a ** race condition** . To avoid this, if someone wants to mutate
3505
+ something that they've borrowed from you, you must not have lent out that
3506
+ pointer to anyone else.
3505
3507
3506
3508
Rust has a sophisticated system called the ** borrow checker** to make sure that
3507
3509
everyone plays by these rules. At compile time, it verifies that none of these
3508
- rules are broken. If there's no problem, our program compiles successfully, and
3509
- there is no runtime overhead for any of this. The borrow checker works only at
3510
- compile time. If the borrow checker did find a problem, it will report a
3511
- ** lifetime error** , and your program will refuse to compile.
3510
+ rules are broken. If our program compiles successfully, Rust can guarantee it
3511
+ is free of data races and other memory errors, and there is no runtime overhead
3512
+ for any of this. The borrow checker works only at compile time. If the borrow
3513
+ checker did find a problem, it will report a ** lifetime error** , and your
3514
+ program will refuse to compile.
3512
3515
3513
3516
That's a lot to take in. It's also one of the _ most_ important concepts in
3514
3517
all of Rust. Let's see this syntax in action:
0 commit comments