Ваша проблема может быть уменьшена до этого:
pub fn scan<'a>(source: &'a str) -> Option<&'a str> {
let chars: Vec<&str> = source.split("").collect();
scan_token(&chars)
}
pub fn scan_token<'a>(chars: &'a [&'a str]) -> Option<&'a str> {
chars.last().cloned()
}
error[E0597]: `chars` does not live long enough
--> src/lib.rs:3:17
|
3 | scan_token(&chars)
| ^^^^^ borrowed value does not live long enough
4 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 1:13...
--> src/lib.rs:1:13
|
1 | pub fn scan<'a>(source: &'a str) -> Option<&'a str> {
| ^^
Функция scan_token
требует, чтобы ссылка на срез и ссылки внутри среза имели одинаковые время жизни: &'a [&'a str]
.Поскольку Vec
живет в течение более короткого периода времени, это и должно быть единой жизнью.Однако время жизни вектора недостаточно велико для возврата значения.
Удалите ненужное время жизни:
pub fn scan_token<'a>(chars: &[&'a str]) -> Option<&'a str>
Применяя эти изменения к вашему полному коду, вы видитеосновная проблема повторяется в определении Token
:
struct Token<'src> {
lexeme: &'src [&'src str],
}
Эта конструкция определенно не позволяет вашему коду компилироваться как есть - нет вектора срезов, который будет существовать до тех пор, покадольки.Ваш код просто невозможен в этой форме.
Вы могли бы передать изменяемую ссылку на Vec
для использования в качестве хранилища, но это было бы довольно необычно и имеет множество недостатковвы нажмете, когда попытаетесь сделать что-то большее:
impl Scanner {
pub fn scan<'src>(&mut self, source: &'src str, chars: &'src mut Vec<&'src str>) -> Vec<Token<'src>> {
// ...
chars.extend(source.graphemes(true));
// ...
while let Some(_) = chars.get(offset) {
// ...
let token = self.scan_token(chars);
// ...
}
// ...
}
// ...
}
fn main() {
// ...
let mut chars = Vec::new();
let tokens = scanner.scan("abcd", &mut chars);
// ...
}
Вы, вероятно, просто хотите, чтобы Token
было Vec<&'src str>
См. также: