Rust中sort_by多条件排序的冗余模式匹配如何简化?
简化Rust多条件排序的冗余代码
直接用Ordering的链式方法then/then_with就能彻底消除嵌套match的冗余,这是Rust标准库专门为多条件排序设计的语法糖。
先看你可能写的冗余实现:
use std::cmp::Ordering; #[derive(Debug, PartialEq)] struct Player { name: String, championships: u32, wins: u32, } fn main() { let mut players = vec![ Player { name: "Alice".into(), championships: 2, wins: 100 }, Player { name: "Bob".into(), championships: 3, wins: 90 }, Player { name: "Charlie".into(), championships: 3, wins: 100 }, ]; // 冗余的嵌套match写法 players.sort_by(|a, b| { let cmp_champs = b.championships.cmp(&a.championships); match cmp_champs { Ordering::Equal => { let cmp_wins = b.wins.cmp(&a.wins); match cmp_wins { Ordering::Equal => a.name.cmp(&b.name), other => other, } } other => other, } }); }
简化后的实现
用then方法链式调用,完全替代嵌套match:
use std::cmp::Ordering; #[derive(Debug, PartialEq)] struct Player { name: String, championships: u32, wins: u32, } fn main() { let mut players = vec![ Player { name: "Alice".into(), championships: 2, wins: 100 }, Player { name: "Bob".into(), championships: 3, wins: 90 }, Player { name: "Charlie".into(), championships: 3, wins: 100 }, ]; // 简洁的链式排序 players.sort_by(|a, b| { b.championships.cmp(&a.championships) .then(b.wins.cmp(&a.wins)) .then(a.name.cmp(&b.name)) }); }
为什么这能行?
Ordering::then方法会先判断当前排序结果:如果不是Equal,直接返回当前结果;如果是Equal,才会执行后面的比较逻辑,完美替代嵌套match的分支判断。- 降序需求直接通过
b.field.cmp(&a.field)实现(默认a.cmp(&b)是升序,反过来就是降序),升序则用a.field.cmp(&b.field)。 - 如果你的排序逻辑需要延迟计算(比如要先对字段做转换再比较),可以用
then_with替代then,它接受一个返回Ordering的闭包:
// 比如name需要转成小写再比较升序 players.sort_by(|a, b| { b.championships.cmp(&a.championships) .then_with(|| b.wins.cmp(&a.wins)) .then_with(|| a.name.to_lowercase().cmp(&b.name.to_lowercase())) });
这种写法不仅消除了冗余的match代码,还让排序逻辑的层级关系一目了然,可读性拉满。
内容的提问来源于stack exchange,提问作者Patrick Bucher
相关产品推荐
相关产品推荐

