generics - 如何从函数返回过滤器迭代器?

标签 generics iterator rust

我想要这样的东西:

fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> ??? {
    input.iter().filter(|&x| x == Int::one())
}

那个函数的返回类型是什么? (我想返回迭代器)

(我希望这不是太明显,我已经尝试了半个小时,现在才开始感到沮丧:p)

编辑:

我尝试按照 here 中的说明进行操作=> playpen link

编译器给我以下错误:

<anon>:5:1: 7:2 error: the trait `core::kinds::Sized` is not implemented for the type `for<'r> core::ops::Fn(&'r T) -> bool + 'a`
<anon>:5 fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> Filter<&T, Iter<'a, T>, Fn(&T) -> bool>{
<anon>:6     input.iter().filter(|&x| x == Int::one())
<anon>:7 }
<anon>:5:1: 7:2 note: required by `core::iter::Filter`
<anon>:5 fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> Filter<&T, Iter<'a, T>, Fn(&T) -> bool>{
<anon>:6     input.iter().filter(|&x| x == Int::one())
<anon>:7 }
<anon>:5:1: 7:2 error: the trait `for<'r> core::ops::Fn(&'r &'a T) -> bool` is not implemented for the type `for<'r> core::ops::Fn(&'r T) -> bool + 'a`
<anon>:5 fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> Filter<&T, Iter<'a, T>, Fn(&T) -> bool>{
<anon>:6     input.iter().filter(|&x| x == Int::one())
<anon>:7 }
<anon>:5:1: 7:2 note: required by `core::iter::Filter`
<anon>:5 fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> Filter<&T, Iter<'a, T>, Fn(&T) -> bool>{
<anon>:6     input.iter().filter(|&x| x == Int::one())
<anon>:7 }
error: aborting due to 2 previous errors
playpen: application terminated with error code 101

我如何告诉 rustc Fn(&T) -> boolSized?

最佳答案

使用rust 1.26

fn filter_one(input: &[u8]) -> impl Iterator<Item = &u8> {
    input.iter().filter(|&&x| x == 1)
}

fn main() {
    let nums = vec![1, 2, 3, 1, 2, 3];
    let other: Vec<_> = filter_one(&nums).collect();
    println!("{:?}", other);
}

使用rust 1.0

fn filter_one<'a>(input: &'a [u8]) -> Box<Iterator<Item = &'a u8> + 'a> {
    Box::new(input.iter().filter(|&&x| x == 1))
}

fn main() {
    let nums = vec![1, 2, 3, 1, 2, 3];
    let other: Vec<_> = filter_one(&nums).collect();
    println!("{:?}", other);
}

此解决方案需要额外分配。我们创建了一个盒装特征对象。在这里,对象的大小始终是已知的(只是一两个指针),但是不需要知道堆中对象的大小。

作为Vladimir Matveev points out ,如果您的谓词逻辑不需要来自环境的任何信息,您可以使用函数而不是闭包:

use std::{iter::Filter, slice::Iter};

fn filter_one<'a>(input: &'a [u8]) -> Filter<Iter<u8>, fn(&&u8) -> bool> {
    fn is_one(a: &&u8) -> bool {
        **a == 1
    }

    input.iter().filter(is_one)
}

fn main() {
    let nums = vec![1, 2, 3, 1, 2, 3];
    let other: Vec<_> = filter_one(&nums).collect();
    println!("{:?}", other);
}

另见:

关于generics - 如何从函数返回过滤器迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31235676/

相关文章:

java - 将泛型类型乘以二 - 二叉树方法

generics - 泛型结构的构造函数中出现 "Expected type parameter"错误

java - 流式传输迭代器的最简单方法

rust - 调用 Rust init 函数时获取 "Cannot deserialize the contract state"

input - 如何在 Rust 1.0 中读取用户输入的整数?

java - 参数化类的 Hibernate 映射

java - 实现 Comparable、compareTo 名称冲突 : "have the same erasure, yet neither overrides the other"

c++ - 插入 std::map 并将获得的迭代器操作到插入的元素

c++ - 在 C 中迭代 C++ 容器

rust - 使用动态数量的 .and() 创建 Diesel.rs 查询