2017-01-22 2 views
19

Учитывая этот код:Почему для хранения ссылки `& 'a T` требуется связанная` T:' a`?

struct RefWrapper<'a, T> { 
    r: &'a T, 
} 

... компилятор жалуется:

error: the parameter type T may not live long enough

consider adding an explicit lifetime bound T: 'a so that the reference type &'a T does not outlive the data it points at.

Я видел эту ошибку несколько раз уже и до сих пор я просто слушал компилятор и все работало нормально , Однако, думая больше об этом, я не понимаю почему Мне нужно написать T: 'a.

Насколько я понял, уже невозможно получить такую ​​ссылку. Имея &'a T, подразумевается, что существует объект типа T, который проживает не менее 'a. Но мы не можем хранить ссылки в указанном объекте, которые указывают на данные, имеющие более короткий срок службы, чем 'a. Это будет уже приведет к ошибке компилятора.

В этом смысле уже невозможно получить &'a T, где T не пережить 'a. Таким образом, дополнительная аннотация (T: 'a) не требуется.

Я прав? Я ошибаюсь, и если да: как я могу сломать код, если T: 'a не требуется?


Ссылки:

+1

I спросил #rust и кажется, что [этот код] (https: // github.ru/rust-lang/rust/issues/24622 # issuecomment-94761287) сломает вещи, если требование 'T: 'a' было отменено. Но я пока не понимаю этот код, и сейчас я перестану пытаться. Надеюсь, кто-то, кто понимает проблему, отвечает тем временем^_^ –

+0

[Соответствующий RFC от августа 2017 года (https://github.com/rust-lang/rfcs/pull/2093) –

ответ

15

Это часть оформленности правил. Тип &'a T является только корректным, если T: 'a («T переживает« a », это необходимо, потому что у нас есть ссылка, с которой мы можем получить доступ в области 'a; указанное значение в T должно быть действительным, по крайней мере, для этого сфера охвата).

struct RefWrapper<'a, T> является универсальным типом и говорит, что вы можете ввести пожизненный 'x и тип U и получить RefWrapper<'x, U> тип обратно. Однако этот тип не обязательно хорошо сформирован или даже реализован, если не соблюдается требование T: 'a.

Это требование исходит из детали реализации; это не обязательно так, что T и 'a используются вместе, как &'a T в внутренних структурах. Требование формообразования скважины необходимо продвигать в открытый интерфейс структуры RefWrapper, так что требования к формированию типа RefWrapper<'_, _> являются общедоступными, даже если внутренняя реализация не является.

(Есть и другие места, где же требование T: 'a возвращается, но неявный:

pub fn foo<'a, T>(x: &'a T) { } 

мы замечаем разницу:. Здесь тип &'a T является частью общественного API, тоже)

+0

Это имеет смысл, спасибо <3 –

Смежные вопросы