use std::fmt::Display;

fn largest<T>(list: &[T]) -> &T
where
    T: PartialOrd + Display
{
    let mut largest = &list[0];
    for item in list.iter() {
        // item: &i32
        // largest: &i32
        // &largest: &&i32
        if item > &largest {
            println!("item > &largest: {}", item > &largest);
        }
        if item > largest {
            println!("item > largest: {}", item > largest);
            largest = &item;
        }
    }
    &largest
}

fn main() {
    let number_list = vec![34, 50, 45];
    let result = largest(&number_list);
    println!("The largest number is {}", result);
}

在最大的函数中,item > largestitem > &largest都可以编译成功

我try 过将&amp;I32与&amp;&amp;I32进行比较,结果显示错误:no implementation for {integer} < &{integer} and {integer} > &{integer}.

let a = 10; // i32
let b = &a; // &i32
let c = &b; // &&i32
println!("{}", b > c);

我预料的是item > &largest会引发类似于b > c的错误. 请告诉我为什么item > &largest可以编译成功,谢谢.

推荐答案

PartialOrd中的This implementation表示,如果a.partial_cmp(b)可用,则(&a).partial_cmp(&b)也可用(在两个参数上都使用*来转接呼叫).

largest<T>()函数中,我们声明T实现PartialOrd,那么item > largest是正确的,因为&T的实现将把调用转发到(*item).partial_cmp(*largest).

item > &largest中,item扮演self的角色,该参数是特殊的,因为编译器自动地(方便地)添加调用点处的所有&,以便与函数签名(see the documentation)中的self的确切类型相匹配. 在这里,编译器将静默地添加&,就像我们已经编写了&item > &largest一样,它将被转发(在&T的实现中)到item > largest(并再次转发到*item > *largest). 所有这些都是可能的,因为编译器知道最终T实现PartialOrd.

在您的abc的示例中,我们不知道a的确切类型;我们假设在最近的默认情况下可以将其推断为i32,但在这一最后的决定之前,没有任何声明该类型将实现PartialOrd. 为了简化调用而在左侧静默添加&的决定无法做出. 如果我们用10_i32强制使用a的类型,那么这种类型就足够早地被知道以实现PartialOrd,那么编译器可以通过默默地将b > c改为&b > c来帮助我们.

Rust相关问答推荐

访问Rust中的隐藏变量

编译项目期间使用Cargo生成时出现rustc错误

如何删除Mac Tauri上的停靠图标?

我无法理解Rust范围的定义(Rust Programming Language,第二版克拉布尼克和尼科尔斯)

为什么rustc会自动降级其版本?

为什么`tokio::main`可以直接使用而不需要任何导入?

从 rust 函数返回 &HashMap

Rust 中的复合 `HashSet` 操作或如何在 Rust 中获得 `HashSet` 的显式差异/并集

Nom 解析器无法消耗无效输入

unwrap 选项类型出现错误:无法移出共享引用后面的*foo

Option<&T> 如何实现复制

当在lambda中通过引用传递时,为什么会出现终身/类型不匹配错误?

(let b = MyBox(5 as *const u8); &b; ) 和 (let b = &MyBox(5 as *const u8); ) 之间有什么区别

有什么方法可以通过使用生命周期来减轻嵌套生成器中的当生成器产生时borrow 可能仍在使用错误?

实现泛型的 Trait 方法中的文字

为什么要这样编译?

Rust/Serde/HTTP:序列化`Option`

是否可以在 Rust 中的特定字符上实现特征?

从函数返回 u32 的数组/切片

缓存自引用函数导致 Rust