Как мне разрешить эту ошибку и что именно я сообщаю компилятору, когда я указываю время жизни на impl Game, когда у меня уже есть время жизни на структуре?
Я подозреваю, что выпутаница проистекает из неполного понимания способа, которым времена жизни объявляются и используются в Rust.
Время жизни структур
Чтобы использовать время жизни в структуре, вы объявляете время жизни внутри <>
рядом с именем структуры, которую вы объявляете, а затем ссылается на это время жизни в определении структуры. Важно отметить, что заявленное время жизни ограничено определением структуры - оно не имеет никакого значения снаружи.
Например (используя MRE, предоставленное @Shepmaster):
struct Game<'a> {
handlers: Vec<&'a str>,
}
СтруктураGame
содержит вектор ссылок на строки, и строки, на которые ссылаются, должны длиться как минимум столько же, сколько структура Game
.
Impl Lifetimes
При использовании спецификатора времени жизни дляблок impl, вы объявляете время жизни внутри <>
рядом с ключевым словом impl, после чего вы можете ссылаться на время жизни как в реализуемой структуре, так и внутри реализациисам по себе, например так:
impl<'b> Game<'b> {
fn match_str(&mut self, label: &'b str) {
self.handlers.push(label);
}
}
Обратите внимание, что я использую здесь совершенно другое имя времени жизни ('b
), чтобы проиллюстрировать, что объявление времени жизни в структуре не зависит от того, которое объявлено в блоке impl.
Разбивка:
impl<'b>
Это означает, что мы определяем реализацию для структуры, и в рамках этого определениядалее мы будем использовать время жизни 'b
Game<'b> {
Это означает, что impl предназначен для структуры Game
с временем жизни 'b
- поэтому любые ссылки на self
внутри этой реализации будут выполняться автоматическитакже имеют время жизни 'b
.
fn match_str(&mut self, label: &'b str) {
Здесь мы определяем метод match_str
, который принимает аргумент label
. label
- это фрагмент строки, который также имеет время жизни 'b
- поэтому он должен длиться как минимум столько же, сколько self
для вызова метода.
В исходном коде у вас было что-токак это:
impl Game<'_> {
fn match_str<'a>(&mut self, label: &'a str) {
...
}
}
Это сообщало компилятору:
- , что вы запускаете новый блок impl, и на уровне impl не объявлено время жизни
- что реализация предназначена для структуры
Game
;эта структура имеет параметр времени жизни, но нас это не волнует, и мы не собираемся связывать его с каким-либо элементом реализации - Мы определяем метод
match_str
, и мы объявляем время жизни 'a
, на который мы можем ссылаться в остальной части сигнатуры функции - У нас есть аргумент
label
, который имеет время жизни a
, но мы не связываем это время жизни с чем-либо еще
Дополнительная информация: