我有以下代码:
fn example(known_primes: &[i32], number: i32, prime: i32, limit: i32) {
let mut is_prime = true;
for prime in known_primes {
if number % prime == 0 {
is_prime = false;
break;
}
if *prime > limit {
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我需要prime在第二个条件(*prime > limit)中取消引用,当我不需要在第一个条件()中这样做时number % prime == 0?
这两个%和<是两个数字并把返回一些运营商.唯一的区别似乎在于它们返回的内容(数字与布尔值).虽然为什么不能将借用的整数与文字整数进行比较? 确实解释了使代码工作所需的内容(所有重载的实现,理想情况下在标准库中),它没有说明它为什么起作用a % b.这些运营商之间是否存在根本区别?或者它还没有实现?
比较运算符实际上的行为与算术运算符不同.在查看特征定义时,差异变得明显.举个例子,这就是PartialEq特质
pub trait PartialEq<Rhs = Self>
where
Rhs: ?Sized,
{
fn eq(&self, other: &Rhs) -> bool;
fn ne(&self, other: &Rhs) -> bool { ... }
}
Run Code Online (Sandbox Code Playgroud)
和Add特点
pub trait Add<RHS = Self> {
type Output;
fn add(self, rhs: RHS) -> Self::Output;
}
Run Code Online (Sandbox Code Playgroud)
我们可以看到比较特征通过引用获取操作数,而算术特征通过值获取操作数.这种差异反映在编译器如何转换运算符表达式中:
a == b ==> std::cmp::PartialEq::eq(&a, &b)
a + b ==> std::ops::Add::add(a, b)
Run Code Online (Sandbox Code Playgroud)
比较的操作数被评估为位置表达式,因此它们永远不会移动值.另一方面,算术运算符的操作数被计算为值表达式,因此根据操作数类型是否移动或复制它们Copy.
由于这种差异的结果,如果我们实行PartialEq的类型A,我们不仅可以比较A和A,但也&A并&A凭借DEREF的强制的操作数.对于Add在另一方面,我们需要一个单独的实施能够添加&A和&A.
我无法回答为什么标准库实现"混合"版本以供算术运算符的引用和值,但不能用于比较.我看不出后者无法完成的根本原因.