mirror of
https://github.com/rust-lang-cn/book-cn.git
synced 2025-01-24 08:00:24 +08:00
Add explicit outer blocks
This commit is contained in:
parent
63a645dd45
commit
8da7f922e9
@ -87,6 +87,7 @@ So how does Rust determine that this code is bad? It compares scopes. Here's an
|
|||||||
example with some annotations:
|
example with some annotations:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
|
{
|
||||||
let r; // -------+-- 'a
|
let r; // -------+-- 'a
|
||||||
// |
|
// |
|
||||||
{ // |
|
{ // |
|
||||||
@ -97,6 +98,7 @@ let r; // -------+-- 'a
|
|||||||
println!("r: {}", r); // |
|
println!("r: {}", r); // |
|
||||||
// |
|
// |
|
||||||
// -------+
|
// -------+
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, we've annotated the lifetime of `r` with `'a`, and the lifetime of `x`
|
Here, we've annotated the lifetime of `r` with `'a`, and the lifetime of `x`
|
||||||
@ -107,6 +109,7 @@ but refers to something with a lifetime of `'b`, and rejects the program, since
|
|||||||
What about an example that _does_ work?
|
What about an example that _does_ work?
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
{
|
||||||
let x = 5; // -----+-- 'a
|
let x = 5; // -----+-- 'a
|
||||||
// |
|
// |
|
||||||
let r = &x; // --+--+-- 'b
|
let r = &x; // --+--+-- 'b
|
||||||
@ -114,6 +117,7 @@ let r = &x; // --+--+-- 'b
|
|||||||
println!("r: {}", r); // | |
|
println!("r: {}", r); // | |
|
||||||
// --+ |
|
// --+ |
|
||||||
// -----+
|
// -----+
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, `x` lives for `'a`, which is larger than `'b`. So this is okay: we know
|
Here, `x` lives for `'a`, which is larger than `'b`. So this is okay: we know
|
||||||
@ -151,6 +155,7 @@ So why do we need to declare lifetimes on functions, but not inside of them?
|
|||||||
Here's our example from before:
|
Here's our example from before:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
|
{
|
||||||
let r;
|
let r;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -159,6 +164,7 @@ let r;
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!("r: {}", r);
|
println!("r: {}", r);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Let's extract that inner block into a function. Remember, this code won't
|
Let's extract that inner block into a function. Remember, this code won't
|
||||||
@ -171,9 +177,11 @@ fn foo() -> &i32 {
|
|||||||
&x
|
&x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
let r = foo();
|
let r = foo();
|
||||||
|
|
||||||
println!("r: {}", r);
|
println!("r: {}", r);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
We get an error:
|
We get an error:
|
||||||
@ -202,9 +210,11 @@ fn foo<'a>() -> &'a i32 {
|
|||||||
&x
|
&x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
let r = foo();
|
let r = foo();
|
||||||
|
|
||||||
println!("r: {}", r);
|
println!("r: {}", r);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here's the error:
|
Here's the error:
|
||||||
@ -236,6 +246,7 @@ that functions which take multiple types need type parameters, functions which
|
|||||||
operate over different lifetimes need lifetime parameters. Think about it like this:
|
operate over different lifetimes need lifetime parameters. Think about it like this:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
|
{
|
||||||
let r; // -------+-- We know that this lifetime starts exactly here...
|
let r; // -------+-- We know that this lifetime starts exactly here...
|
||||||
// |
|
// |
|
||||||
{ // |
|
{ // |
|
||||||
@ -246,6 +257,7 @@ let r; // -------+-- We know that this lifetime starts exactly here...
|
|||||||
println!("r: {}", r); // |
|
println!("r: {}", r); // |
|
||||||
// |
|
// |
|
||||||
// -------+-- ... and ends here.
|
// -------+-- ... and ends here.
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
But in this case:
|
But in this case:
|
||||||
@ -257,6 +269,7 @@ fn foo<'a>() -> &'a i32 {
|
|||||||
&x
|
&x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
let r1 = foo(); // -----+-- 'r1 starts here
|
let r1 = foo(); // -----+-- 'r1 starts here
|
||||||
// |
|
// |
|
||||||
println!("r: {}", r1); // |
|
println!("r: {}", r1); // |
|
||||||
@ -266,6 +279,7 @@ let r2 = foo(); // --+--+-- 'r2 starts here
|
|||||||
println!("r2: {}", r1); // | |
|
println!("r2: {}", r1); // | |
|
||||||
// --+--+-- 'r2 ends
|
// --+--+-- 'r2 ends
|
||||||
// -----+-- 'r1 ends
|
// -----+-- 'r1 ends
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
That parameter, `'a`, will represent `'r1` in the first case, and `'r2` in the
|
That parameter, `'a`, will represent `'r1` in the first case, and `'r2` in the
|
||||||
|
Loading…
Reference in New Issue
Block a user