这里我有一个(char,usize)对的矢量vec,我想写一个函数
fn take_lt(&'a vec, cutoff: usize) -> Iterator<'a, char>
它返回一个迭代器,它在匹配值小于cutoff的字符上 .
-
有没有办法做到这一点,没有分配东西堆的开销(即装箱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)
^~~~~~~~
一点google搜索建议我尝试将函数项转换为函数指针,如:
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
...
2 回答
你很亲密:
作为替代方案,您可以创建自己的结构,实现所需的迭代器逻辑并返回该结构 . 例如:
每个函数都有一个独特的,不同的类型,与
fn
类型兼容 . 这反映了闭包也有不同类型的事实 . 这是编译器通过found fn item
的含义:它没有找到您在返回类型中指定的fn
类型,而是cmp_fun
函数的唯一类型 .fn
类型已经是指针,所以不需要(至少在你的情况下)引用fn
;你可以直接拿一个fn
. 通过这样做,编译器将隐式地将函数转换为更通用的fn
类型 .