sort_by的比较器参数


let mut intervals = vec![vec![1,8], vec![2,4]];
intervals.sort_by(|a, b| a[1].cmp(&b[1]));
  • 这是有效的,但我不确定这与书中下面的函数定义F如何匹配
pub fn sort_by<F>(&mut self, compare: F)
where
F: FnMut(&T, &T) -> Ordering,
  • 编译rust程序时,<instance>.<method>(<argument>)会变成<method>(&<instance>,<argument>)

没有"闭包";在Rust中键入。相反,对于每个闭包,编译器都会创建一个类型来存储捕获的值。然后,根据闭包的特征,为闭包的类型分配Fn特征的实现:

  • 所有闭包都是FnOnce
  • 不消耗任何捕获值并且可能(或可能不(突变捕获值的闭包是FnMut
  • 不消耗或变异任何捕获值的闭包是Fn

所有为Fn的闭包都是FnMut,所有为FnMut的闭包都为FnOnce

为了支持所有合适的闭包,sort_by方法对受FnMut特性约束的类型F是通用的。这允许sort_by的通用实现重复调用所提供的函数(在这方面,更通用的特性FnOnce是不够的(。

用闭包调用sort_by会调用sort_by::< _type_of_the_closure_ >,但这里推断出类型参数,甚至不能显式给出,因为闭包类型是不可调用的。

在这个特定的用例中,返回从正在排序的值中提取的std::cmp::Ord值的比较,sort_by_key将更合适。

let mut intervals = vec![vec![1,8], vec![2,4]];
intervals.sort_by_key(|a| a[1]);

至于你的另一个问题,instance.method(argument)通常相当于[Type/Trait]::method([&instance/&mut instance/instance], argument)。方法只是在一个类型下使用名称空间的函数,它们的第一个参数就是这个类型。一个细微的区别是instance.method(argument)自动取消引用和/或获取对instance的引用,而[Type/Trait]::method要求第一个参数的类型准确。