Чтобы выучить Rust, я пишу библиотеку синтаксических анализаторов. Теперь у меня есть проблема, которая охватывает сложный тип сечения и владение. У меня есть некоторые функции строительных блоков, которые я хотел бы использовать отдельно:
pub fn achar(character: char) -> impl Fn(&str) -> Option<char> {
move |input| match input.chars().next() {
Some(c) if c == character => Some(c),
_ => None,
}
}
pub fn alternatives<'a, T>(
alts: &'a [impl Fn(&'a str) -> Option<T>],
) -> impl Fn(&'a str) -> Option<T> {
move |input| {
for alt in alts.iter() {
let tried = alt(input);
if tried.is_none() {
continue;
}
return tried;
}
None
}
}
pub fn one_of<'a>(allowed: &'a str) -> impl Fn(&'a str) -> Option<char> {
let v = allowed.chars().map(achar).collect::<Vec<_>>();
alternatives(&v)
}
Использование будет выглядеть следующим образом:
fn main() {
println!("{:?}", achar('f')("foo"));
println!("{:?}", alternatives(vec![achar('f'), achar('b')])("foo"));
println!("{:?}", one_of("foo")("foo"));
}
Вот так я получаю следующую ошибку:
= note: expected type `for<'r> fn(&'r str) -> std::option::Option<char> {any_char}`
found reference `&impl for<'r> std::ops::Fn<(&'r str,)>`
Я бы сказал, что quote
реализует Fn(&str)
, не так ли? Как я могу заставить это работать?
Как только это будет решено, следующая проблема находится у двери:
33 | alternatives(&v)
| ^^^^^^^^^^^^^--^
| | |
| | `v` is borrowed here
| returns a value referencing data owned by the current function
Конечно, встраивание не решает проблему. Я понятия не имею, как можно go атаковать это.
Детская площадка доступна здесь.