Привет!
Здесь есть несколько проблем. Во-первых, у self не нужно указывать тип. Во-вторых, lifetime elision в данном случае не сработает правильно, и все аннотации нужно писать явно. В-третьих, интерфейс не совсем корректный - если в коллекции ничего нет, то pop() вернёт None, но исходная коллекция будет недоступна, потому что метод принимает self по значению. Для &str это не страшно, потому что он Copy, но для других коллекций вроде Vec уже будут проблемы. Поэтому пустую коллекцию нужно возвращать обратно - если она не понадобится, то значение можно будет просто проигнорировать.
Вот рабочий вариант:
pub trait Seq<T> {
fn pop(self) -> Result<(T, Self), Self>;
}
impl<'a> Seq<char> for &'a str {
fn pop(self) -> Result<(char, &'a str), &'a str> {
if self.is_empty() {
Err(self)
} else {
Ok((self.char_at(0), self.slice_from(1)))
}
}
}
fn process(s: &str) {
match s.pop() {
Ok((c, rest)) => {
println!("{}<{}>", c, rest);
process(rest);
}
Err(s) => println!("<{}> is empty", s)
}
}
fn main() {
let s = "abcdefg";
process(s);
}
play