Здесь у меня есть вектор VEC из (полукокса, usize) пар, и я хочу, чтобы написать функциюКак вернуть результат вызова filter_map
fn take_lt(&'a vec, cutoff: usize) -> Iterator<'a, char>
который возвращает итератор символов, соответствующих значений меньше отсечки.
- Есть ли способ сделать это без накладных расходов, выделяя что-то в кучу (т.е. боксирование среды Fn или создание другого вектора)?
- Есть ли способ сделать это
без необходимости явно выписывать отвратительное связанное с ним возвращение типа?
После попытки этого много различных способов (несколько из которых составлено, но все из которых участвуют распределение кучи, которые я хотел бы избежать), я придумал:
use std::iter::repeat;
use std::iter::FilterMap;
use std::iter::Zip;
use std::iter::Repeat;
use std::slice;
fn take_lt<'a>(vec: &'a[(char, usize)], cutoff: usize) -> FilterMap<Zip<slice::Iter<'a, (char, usize)>, Repeat<usize>>, &fn((&(char, usize), usize)) -> Option<char>> {
fn cmp_fun((&(x, a), b): (&(char, usize), usize)) -> Option<char> {
if a < b {
Some(x)
} else {
None
}
}
vec.iter().zip(repeat(cutoff)).filter_map(&cmp_fun)
}
Это близко , но я получаю:
src/lib.rs:15:47: 15:55 error: mismatched types:
expected `&fn((&(char, usize), usize)) -> core::option::Option<char>`,
found `&fn((&(char, usize), usize)) -> core::option::Option<char> {take_lt::cmp_fun}`
(expected fn pointer,
found fn item) [E0308]
src/lib.rs:15 vec.iter().zip(repeat(cutoff)).filter_map(&cmp_fun)
^~~~~~~~
немного прибегая к помощи предлагает мне попробовать литье элемент функции на указатель функции, как:
vec.iter().zip(repeat(cutoff)).filter_map(&(cmp_fun as fn((&(char, usize), usize)) -> Option<char>))
но терпит неудача с:
src/lib.rs:15:49: 15:103 error: borrowed value does not live long enough
src/lib.rs:15 vec.iter().zip(repeat(cutoff)).filter_map(&(cmp_fun as fn((&(char, usize), usize)) -> Option<char>))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:7:167: 16:2 note: reference must be valid for the lifetime 'a as defined on the block at 7:166...
src/lib.rs: 7 fn take_lt<'a>(vec: &'a[(char, usize)], cutoff: usize) -> FilterMap<Zip<slice::Iter<'a, (char, usize)>, Repeat<usize>>, &fn((&(char, usize), usize)) -> Option<char>> {
src/lib.rs: 8 fn cmp_fun((&(x, a), b): (&(char, usize), usize)) -> Option<char> {
src/lib.rs: 9 if a < b {
src/lib.rs:10 Some(x)
src/lib.rs:11 } else {
src/lib.rs:12 None
...
src/lib.rs:7:167: 16:2 note: ...but borrowed value is only valid for the block at 7:166
src/lib.rs: 7 fn take_lt<'a>(vec: &'a[(char, usize)], cutoff: usize) -> FilterMap<Zip<slice::Iter<'a, (char, usize)>, Repeat<usize>>, &fn((&(char, usize), usize)) -> Option<char>> {
src/lib.rs: 8 fn cmp_fun((&(x, a), b): (&(char, usize), usize)) -> Option<char> {
src/lib.rs: 9 if a < b {
src/lib.rs:10 Some(x)
src/lib.rs:11 } else {
src/lib.rs:12 None
...
Дубликат http://stackoverflow.com/questions/27535289/correct-way-to-return-an-iterator. – Shepmaster