我正在学习Rust,我想了解函数调用之间的区别

    S::foo(&s); 
    T::foo(&s);
    <S as T>::foo(&s);

1为什么我们需要所有这些方式?有什么不同呢?

2我们应该在哪里使用它?

struct S;

trait T {
    fn foo(&self);
}

impl T for S {
    fn foo(&self) {
        println!("XXX");        
    }
}


fn main() {
    let s = S;
    s.foo(); // (It's clear)
    S::foo(&s); 
    T::foo(&s);
    <S as T>::foo(&s);
}

推荐答案

尽可能和明确地使用方法语法s.foo(),它是最不冗长的,并且应用了自动取消引用,这样您的代码将更加干净.

Self类型不明确时,S::foo(&s)主要是有用的,它经常与From::from一起使用,以避免.into()上的涡鱼,或者在例如Rc::clone的情况下,以避免混淆,如果它是引用计数器的廉价增加或更昂贵的内值克隆.

当同时存在固有的foo和特征实现时,T::foo(&s)是必需的:

// in addition to your definitions this exists
impl S {
    fn foo(&self) {
        println!("S")
    }
}
S::foo(&s); // -> prints S
T::foo(&s); // -> prints XXX

当将最后两种情况组合在一起时,可以使用完全限定语法<S as T>::foo(&s).

Rust相关问答推荐

在‘await’点上使用‘std::同步::Mutex’是否总是会导致僵局?

即使参数和结果具有相同类型,fn的TypId也会不同

为什么我可以跟踪以前borrow 过的变量?房主在哪里?

获取字符串切片(&;str)上的切片([ia..ib])返回字符串

在跨平台应用程序中使用std::OS::Linux和std::OS::Windows

使用Box优化可选的已知长度数组的内存分配

定义只有一些字段可以缺省的 struct

如何从ruust中的fig.toml中读取?

Rust中WPARAM和VIRTUAL_KEY的比较

为什么将易错函数的泛型结果作为泛型参数传递 infer ()?不应该是暧昧的吗?

Rust:为什么 &str 不使用 Into

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

更新 rust ndarray 中矩阵的一行

pyO3 和 Panics

使用 Rust 从 Raspberry Pi Pico 上的 SPI 读取值

`移动||异步移动{...}`,如何知道哪个移动正在移动哪个?

无法把握借来的价值不够长寿,请解释

TinyVec 如何与 Vec 大小相同?

类型组的通用枚举

Rust 为什么 (u32, u32) 的枚举变体的大小小于 (u64)?