Почему заимствованный строковый литерал переживает своего владельца, притворяясь на всю жизнь? - PullRequest
0 голосов
/ 09 января 2019

Я понимаю, что заем не может пережить существование того, на что он указывает, чтобы уничтожить висячие указатели.

Заем или псевдоним могут пережить владельца, подделав время жизни:

fn main() {
    let e;
    let first = "abcd";
    {
        let second = "defgh";
        e = longest(first, second);
    }
    println!("{}", e);
}

fn longest<'a>(first: &'a str, second: &'a str) -> &'a str {
    if first.len() > second.len() {
        first
    } else {
        second
    }
}

Результат:

defgh

В приведенном выше примере переменная e имеет более длительное время жизни, чем переменная second, и время жизни переменных first & second явно различается.

Когда e инициализируется с помощью longest(first, second), он получает переменную second, время жизни которой до вызова функции фальсифицируется, поскольку оно равно first, но оно ограничено блоком и присвоено e который переживет second. Почему это нормально?

1 Ответ

0 голосов
/ 09 января 2019

Это связано с тем, что оба они имеют время жизни 'static.

Вот пример, который не работает, потому что str здесь не живет для жизни программы, как &'static str. Единственное изменение - следующая строка: let second = String::from("defgh"); и следующая строка, где она передается самой длинной функции.

fn main() {
    let e;
    let first = "abcd";
    {
        let second = String::from("defgh");
        e = longest(first, &second);
    }
    println!("{}", e);
}

fn longest<'a>(first: &'a str, second: &'a str) -> &'a str {
    if first.len() > second.len() {
        first
    } else {
        second
    }
}

Вот ошибка:

error[E0597]: `second` does not live long enough
 --> src/main.rs:6:28
  |
6 |         e = longest(first, &second);
  |                            ^^^^^^^ borrowed value does not live long enough
7 |     }
  |     - `second` dropped here while still borrowed
8 |     println!("{}", e);
  |                    - borrow later used here

Дополнительную информацию можно найти в Static - Rust By Example

...