欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
AtomGit 仓库地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_rust_cargo

本文讲解鸿蒙 PC 端 Rust 开发环境搭建,鸿蒙基于 musl 库、强制二进制签名,无法直接使用通用 Linux 编译产物。需借助鸿蒙专属包管理器 Harmonybrew,提供两套编译方案:方案一安装 llvm-gcc-compat,零配置开箱即用;方案二仅安装 ohos-sdk,需手动配置 Cargo 链接器,二者都依托 ohos-sdk 完成自动签名编译。

可以来参考一下这个文章搭建环境OpenHarmony 鸿蒙 PC + CodeArts IDE 实现 Rust开发完整开发环境搭建指南


一、Rust itertools 是什么

itertools 是 Rust 第三方迭代器增强库,标准库 Iterator 功能比较单薄,这个库补充大量实用迭代工具:

  1. 排列、组合、笛卡尔积、带重复组合(算法常用)
  2. 分组、去重、窗口滑动、相邻配对、交叉合并
  3. 批量变换、折叠、分块、平铺、链式处理
  4. 惰性迭代,性能高,内存占用小
二、第一步创建 Rust 项目并安装依赖

你之前报错是因为在 Python 文件夹执行 cargo,必须先建 Rust 项目:

# 1. 退出python目录,新建rust项目
cd /storage/Users/currentUser/workspace/code/
cargo new iter_demo
cd iter_demo

# 2. 添加itertools依赖
cargo add itertools

此时项目内会生成 Cargo.toml,里面自动写入依赖:

[dependencies]
itertools = "0.13"

请添加图片描述

三、完整可运行 main.rs(复制覆盖全部内容)
use itertools::Itertools;

fn main() {
    // ========== 1. 笛卡尔积 cartesian_product ==========
    let nums = [1, 2];
    let chars = ['a', 'b'];
    let product: Vec<_> = nums.iter().cartesian_product(chars.iter()).collect();
    println!("笛卡尔积: {:?}", product);

    // ========== 2. 全排列 permutations ==========
    let arr = [1, 2, 3];
    let perm: Vec<_> = arr.iter().permutations(2).collect();
    println!("2元素全排列: {:?}", perm);

    // ========== 3. 组合 combinations ==========
    let comb: Vec<_> = arr.iter().combinations(2).collect();
    println!("2元素组合: {:?}", comb);

    // ========== 4. 可重复组合 combinations_with_replacement ==========
    let comb_rep: Vec<_> = [1, 2].iter().combinations_with_replacement(2).collect();
    println!("可重复组合: {:?}", comb_rep);
    println!("----------------------------------------");

    // ========== 5. chain 拼接迭代器 ==========
    let ch: Vec<_> = [1, 2].iter().chain([3, 4].iter()).collect();
    println!("chain拼接: {:?}", ch);

    // ========== 6. tuple_windows 滑动窗口 ==========
    let slide: Vec<_> = [10, 20, 30, 40].iter().tuple_windows::<(_, _)>().collect();
    println!("相邻二元滑动窗口: {:?}", slide);

    // ========== 7. chunk_by 分组(替代废弃 group_by) ==========
    let data = vec![1, 1, 2, 2, 2, 3];
    let groups: Vec<_> = data
        .iter()
        .chunk_by(|&&x| x)
        .into_iter()
        .map(|(k, g)| (k, g.collect::<Vec<_>>()))
        .collect();
    println!("分组结果: {:?}", groups);

    // ========== 8. unique 去重 ==========
    let dup = [1, 2, 2, 3, 3, 3];
    let uniq: Vec<_> = dup.iter().unique().collect();
    println!("去重: {:?}", uniq);

    // ========== 9. interleave 交叉合并 ==========
    let a = [1, 3, 5];
    let b = [2, 4, 6];
    let inter: Vec<_> = a.iter().interleave(b.iter()).collect();
    println!("交叉合并: {:?}", inter);

    // ========== 10. reduce 累加(替代废弃 fold1,into_iter 取出数值而非引用) ==========
    let sum = [1, 2, 3, 4].into_iter().reduce(|a, b| a + b);
    println!("累加总和: {:?}", sum.unwrap());
}

请添加图片描述

四、运行命令

iter_demo 目录执行:

cargo run
五、输出结果预览
笛卡尔积: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
2元素全排列: [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
2元素组合: [[1, 2], [1, 3], [2, 3]]
可重复组合: [[1, 1], [1, 2], [2, 2]]
----------------------------------------
chain拼接: [1, 2, 3, 4]
相邻二元滑动窗口: [(10, 20), (20, 30), (30, 40)]
分组结果: [(1, [1, 1]), (2, [2, 2, 2]), (3, [3])]
去重: [1, 2, 3]
交叉合并: [1, 2, 3, 4, 5, 6]
累加总和: 10

这段代码是 itertools 库十大高频迭代器工具示例,itertools 是Rust标准迭代器的增强扩展库,提供Python itertools同款组合、排列、分组、窗口、去重等能力。

前置依赖说明

使用前必须在 Cargo.toml 添加依赖:

[dependencies]
itertools = "0.13"

导入:use itertools::Itertools;,所有扩展方法都通过这个trait挂载到迭代器上。


1. cartesian_product 笛卡尔积

let nums = [1, 2];
let chars = ['a', 'b'];
let product: Vec<_> = nums.iter().cartesian_product(chars.iter()).collect();
println!("笛卡尔积: {:?}", product);

作用

两个迭代器所有元素两两配对,数学笛卡尔积,顺序:(第一个迭代器元素, 第二个迭代器元素)

输出

笛卡尔积: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

关键点

  • cartesian_product(另一迭代器),不消耗原数组,.iter() 产出引用
  • 适合多维度枚举、双循环简化

2. permutations 全排列

let arr = [1, 2, 3];
let perm: Vec<_> = arr.iter().permutations(2).collect();
println!("2元素全排列: {:?}", perm);

作用

从序列中选 k 个元素,有序、不重复选取,元素顺序不同算两种结果(排列)

输出

2元素全排列: [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]

区分重点

排列关心顺序,[1,2][2,1] 是不同项;参数2代表每组长度为2。
如果不传参数 .permutations() 会生成全部元素的完整全排列。


3. combinations 组合

let comb: Vec<_> = arr.iter().combinations(2).collect();
println!("2元素组合: {:?}", comb);

作用

选k个元素,无序、不重复选取,只保留升序唯一一组

输出

2元素组合: [[1, 2], [1, 3], [2, 3]]

和permutations对比

组合只保留不重复集合,没有反向项;排列区分顺序。


4. combinations_with_replacement 可重复组合

let comb_rep: Vec<_> = [1, 2].iter().combinations_with_replacement(2).collect();
println!("可重复组合: {:?}", comb_rep);

作用

允许同一个元素重复选取,无序组合

输出

可重复组合: [[1, 1], [1, 2], [2, 2]]

使用场景

骰子、可重复抽奖、多选可重复场景


5. chain 迭代器拼接

let ch: Vec<_> = [1, 2].iter().chain([3, 4].iter()).collect();
println!("chain拼接: {:?}", ch);

作用

把多个迭代器首尾拼接成一个,标准库也有chain,但itertools支持多链链式调用

输出

chain拼接: [1, 2, 3, 4]

拓展

iter1.chain(iter2).chain(iter3) 拼接任意数量序列


6. tuple_windows 固定长度滑动窗口

let slide: Vec<_> = [10, 20, 30, 40].iter().tuple_windows::<(_, _)>().collect();
println!("相邻二元滑动窗口: {:?}", slide);

作用

滑动窗口,一次性返回元组,无需手动zip,泛型指定窗口长度
<(_, _)> = 窗口大小2;<(_,_,_)> = 窗口大小3

输出

相邻二元滑动窗口: [(10, 20), (20, 30), (30, 40)]

对比标准库

标准库只有 .windows() 返回切片,tuple_windows 直接返回元组,解构更方便。


7. chunk_by 按条件分组

let data = vec![1, 1, 2, 2, 2, 3];
let groups: Vec<_> = data
    .iter()
    .chunk_by(|&&x| x)
    .into_iter()
    .map(|(k, g)| (k, g.collect::<Vec<_>>()))
    .collect();
println!("分组结果: {:?}", groups);

作用

相邻且key相同的元素分为一组,key由闭包生成

执行流程

  1. chunk_by(|&&x| x):用元素自身作为分组key
  2. 返回 Chunk 迭代器,每个item是 (key, 同组元素迭代器)
  3. map把每组迭代器收集成Vec,方便打印

输出

分组结果: [(1, [1, 1]), (2, [2, 2, 2]), (3, [3])]

注意

只对连续相同key分组,不全局分组;如果需要全局分组要配合 sorted 先排序。


8. unique 迭代器去重

let dup = [1, 2, 2, 3, 3, 3];
let uniq: Vec<_> = dup.iter().unique().collect();
println!("去重: {:?}", uniq);

作用

遍历迭代器,自动过滤重复元素,保留第一次出现的值

输出

去重: [1, 2, 3]

拓展变体

  • unique_by(|x| 关键字):按自定义字段去重

9. interleave 交叉合并两个迭代器

let a = [1, 3, 5];
let b = [2, 4, 6];
let inter: Vec<_> = a.iter().interleave(b.iter()).collect();
println!("交叉合并: {:?}", inter);

作用

交替取a一个、b一个,穿插合并

输出

交叉合并: [1, 2, 3, 4, 5, 6]

长短序列规则

如果两个迭代器长度不同,短的耗尽后,直接追加长迭代器剩余元素。


10. reduce 迭代器归约求和(标准库原生,itertools兼容)

let sum = [1, 2, 3, 4].into_iter().reduce(|a, b| a + b);
println!("累加总和: {:?}", sum.unwrap());

作用

迭代器累计聚合,第一个值作为初始累加器,依次和下一个元素运算

细节区分

  1. .into_iter():获取数组所有权,得到数字i32,不是引用,才能直接相加
  2. reduce 返回 Option<T>:空迭代器返回None,所以用.unwrap()
  3. 替代旧版itertools废弃的fold1,现在标准库自带reduce

输出

累加总和: 10

同类方法

  • fold(初始值, 闭包):可自定义初始值
  • sum():数字专用求和简化写法

完整运行输出汇总

笛卡尔积: [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
2元素全排列: [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]
2元素组合: [[1, 2], [1, 3], [2, 3]]
可重复组合: [[1, 1], [1, 2], [2, 2]]
----------------------------------------
chain拼接: [1, 2, 3, 4]
相邻二元滑动窗口: [(10, 20), (20, 30), (30, 40)]
分组结果: [(1, [1, 1]), (2, [2, 2, 2]), (3, [3])]
去重: [1, 2, 3]
交叉合并: [1, 2, 3, 4, 5, 6]
累加总和: 10

核心使用场景总结

  1. 组合/排列:算法枚举、密码生成、选项遍历
  2. 窗口/分组:时序数据、日志分段、相邻差值计算
  3. 合并交叉:多路数据流合并
  4. 去重笛卡尔积:多条件筛选、多维匹配
关键注意点
  1. 必须在 Rust 项目根目录(存在 Cargo.toml)执行 cargo 命令,不能在 Python 文件夹运行;
  2. 代码头部 use itertools::prelude::*; 一次性导入所有拓展迭代器方法;
  3. Rust 迭代器惰性求值,.collect() 才会把结果转成集合打印;
  4. group_by 使用前数据最好排序,否则相同元素不连续会分成多组。
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐