You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Rust实现类似C++ std::copy_if的泛型集合克隆筛选函数

实现Rust中类似C++ std::copy_if的泛型集合筛选克隆函数

原代码的问题

  • 先克隆整个集合再删除元素的方式效率低下,且不适用于所有集合类型(比如部分集合没有便捷的单元素删除方法)
  • 泛型约束冗余且限制过多:同时要求Clone + Copy没必要,IntoIterator<Item = &'a ItemType>只能处理引用迭代,无法直接接收值类型集合
  • 遍历逻辑错误:res.into_iter()会转移res的所有权,遍历过程中无法修改原集合,导致res.remove()无法调用

正确的通用实现

我们可以利用Rust的迭代器特性和FromIterator trait,实现一个适配所有集合类型的clone_if函数,只克隆符合条件的元素并收集到目标集合中:

use std::borrow::Borrow;

fn clone_if<Input, ItemType, Pred, Output>(input: Input, pred: Pred) -> Output
where
    Input: IntoIterator,
    Input::Item: Borrow<ItemType>,
    ItemType: Clone,
    Pred: Fn(&ItemType) -> bool,
    Output: FromIterator<ItemType>,
{
    input.into_iter()
        .filter(|item| pred(item.borrow()))
        .map(|item| item.borrow().clone())
        .collect()
}

fn main() {
    let first_list = vec![1, 2, 3, 4, 5, 6];
    
    // 输入值类型集合,返回Vec<i32>
    let even_values = clone_if(first_list.clone(), |&item| item % 2 == 0);
    assert_eq!(vec![2, 4, 6], even_values);
    
    // 输入引用类型集合,返回Vec<i32>
    let even_refs = clone_if(&first_list, |item| item % 2 == 0);
    assert_eq!(vec![2, 4, 6], even_refs);
    
    // 也可以适配其他集合类型,比如HashSet
    use std::collections::HashSet;
    let set: HashSet<i32> = [1,2,3,4,5,6].into();
    let even_set: HashSet<i32> = clone_if(&set, |&item| item % 2 == 0);
    assert!(even_set.contains(&2) && even_set.contains(&4) && even_set.contains(&6));
}

实现说明

  • 泛型约束设计:
    • Input: IntoIterator:允许函数接收任何可转换为迭代器的类型(值或引用)
    • Input::Item: Borrow<ItemType>:统一处理值和引用类型的迭代元素,确保能获取到ItemType的引用
    • ItemType: Clone:保证元素可以被克隆
    • Output: FromIterator<ItemType>:允许将筛选后的克隆元素收集到任意实现了该trait的集合类型中(Vec、HashSet等)
  • 迭代器流程:
    1. 将输入转换为迭代器
    2. 使用filter保留符合条件的元素
    3. 克隆筛选后的元素
    4. 用collect将元素收集到目标集合类型中

针对Vec的简化实现

如果只需要针对Vec优化,可以简化约束,直接利用Vec的迭代器特性:

fn vec_clone_if<T, Pred>(vec: Vec<T>, pred: Pred) -> Vec<T>
where
    T: Clone,
    Pred: Fn(&T) -> bool,
{
    vec.into_iter()
        .filter(pred)
        .cloned()
        .collect()
}

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:17:05