Разница между временем жизни "p: & 'a i32" и "p: &' static i32" в Rust? - PullRequest
1 голос
/ 04 октября 2019

Я начал изучать Rust несколько дней назад.

Это выдержка из известной книги Джима Блэнди Programming Rust .

Для кода

fn g<'a>(p: &'a i32) { ... }

let x = 10;
g(&x);

В книге написано:

Rust. Выберите наименьшее возможное время жизни для & x, для звонка в g. Это отвечает всем ограничениям: оно не переживает x и включает весь вызов g. Так что код должен собрать.

Q1. Что подразумевается под наименьшим возможным временем жизни для &x?

Для кода

fn f(p: &'static i32) { ... }

let x = 10;
f(&x);

Q2. Почему этот код не работает? Насколько я понимаю, &'static используется для статических глобальных переменных, которые существуют для полной программы. ссылка

Ответы [ 2 ]

2 голосов
/ 04 октября 2019

A 'static Срок службы - это особая концепция. Он указывает, что переменная, на которую ссылается это, должна существовать в течение всего жизненного цикла программы whole . Использование этого является редким случаем и требует выполнения даже более редких мер предосторожности.

На практике ссылка &'static может иметь место только в двух случаях:

  • A const объявление
  • A static объявление

Оба эффективно выполняют одно и то же, по-разному;различия не важны для этого вопроса, как бы то ни было. В обоих случаях результатом является переменная, которая доступна в течение всего времени жизни программы и не будет перемещена, что гарантирует &'static в случае заимствования.

Теперь, когда мы рассмотрели это, давайте рассмотрим обаваших вопросов.


Q1. Что подразумевается под наименьшим возможным временем жизни для & x?

Когда вы определяете функцию как fn g<'a>(p: &'a i32) { ... }, вы требуете, чтобы p был действительным в течение жизни 'a;это время жизни определяется компилятором, так что 'a является наименьшим возможным . Если ссылка никогда не используется за пределами области действия функции, например, 'a будет временем жизни выполнения этой функции. Если вы используете или ссылаетесь на этот заем вне функции, время жизни (очевидно) будет больше.

Определение «наименьшего возможного» простое: компилятор выведет время жизни, основанное на времени, которое вы началиссылка, в последний раз, когда вы используете эту ссылку. Зависимые заимствования также учитываются, и это, как правило, приводит к укусам людей при работе с коллекциями.

Причина, по которой это наименьшее возможное значение, заключается в том, что вы не столкнетесь с сумасшедшими ситуациями, когда у вас нет ссудно это все равно заимствовано;это обычно происходит, когда вы пытаетесь предоставить свои собственные, неправильные, пожизненные подсказки. Существует множество случаев, когда компилятору лучше всего решить;другой случай - это struct реализации, такие как:

struct Foo<'a> {
    item: &'a u32
}
impl<'a> Foo<'a> {
    pub fn compare<'b>(&self, other: &'b u32) {
        ...
    }
}

Распространенная ошибка в подобных ситуациях заключается в описании other для компилятора как 'a, , а не определение второго 'b срока службы и, таким образом (случайно), требующего other заимствования для срока службы самого struct.


Q2. Почему этот код не работает? Насколько я понимаю, & 'static используется для статических глобальных переменных, которые существуют для полной программы.

let x = 10;

Это назначение не имеет 'static времени жизни. Время жизни анонимного устройства определено как 'static, поскольку оно не строго , определенное как глобальное. единственный способ получить заимствование 'static на что-либо, если этот исходный элемент определен как const или static.

Вы можете убедиться в этом с помощью этого фрагмента ( детская площадка ):

fn f(p: &'static i32) {
    println!("{}", p)
}

const FOO:i32 = 3;
static BAR:i32 = 4;

fn main() {
    f(&FOO); // Works
    f(&BAR); // Also works
}
f(&x);
1 голос
/ 04 октября 2019

A 'static требование времени жизни для ссылки требует, чтобы этот аргумент был объявлен для глобального времени жизни программы, но x не может выполнить это условие, поскольку оно объявлено в середине выполнения.

в состоянии использовать это, объявите x как const или static, поэтому его время жизни будет 'static, и код будет работать нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...