Rustlings Traits4.rs 为什么 impl Trait 语法有效,但特征绑定语法或 where 子句不起作用

the*_*man 2 rust

我正在做 Rustlings 课程 Traits4.rs 练习。任务基本上是为compare_license_types函数选择正确的签名。使用impl Trait如下语法效果很好:

pub trait Licensed {
    fn licensing_info(&self) -> String {
        "some information".to_string()
    }
}

struct SomeSoftware {}

struct OtherSoftware {}

impl Licensed for SomeSoftware {}
impl Licensed for OtherSoftware {}

fn compare_license_types(software: impl Licensed, software_two: impl Licensed) -> bool
{
    software.licensing_info() == software_two.licensing_info()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn compare_license_information() {
        let some_software = SomeSoftware {};
        let other_software = OtherSoftware {};

        assert!(compare_license_types(some_software, other_software));
    }

    #[test]
    fn compare_license_information_backwards() {
        let some_software = SomeSoftware {};
        let other_software = OtherSoftware {};

        assert!(compare_license_types(other_software, some_software));
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我将函数签名更改为使用特征绑定语法或where子句,它将不再编译:

fn compare_license_types<T: Licensed>(software: T, software_two: T) -> bool {}
// Or
fn compare_license_types<T>(software: T, software_two: T) -> bool
where T: Licensed {}
Run Code Online (Sandbox Code Playgroud)

两者都因编译错误而失败:

error[E0308]: mismatched types
  --> exercises/traits/traits4.rs:37:54
   |
37 |         assert!(compare_license_types(some_software, other_software));
   |                                                      ^^^^^^^^^^^^^^ expected struct `SomeSoftware`, found struct `OtherSoftware`

error[E0308]: mismatched types
  --> exercises/traits/traits4.rs:45:55
   |
45 |         assert!(compare_license_types(other_software, some_software));
   |                                                       ^^^^^^^^^^^^^ expected struct `OtherSoftware`, found struct `SomeSoftware`
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?

isa*_*tfa 5

fn compare_license_types<T: Licensed>(software: T, software_two: T) -> bool { ...
Run Code Online (Sandbox Code Playgroud)

告诉编译器softwaresoftware_two都有类型T,其中T可以是任何实现Licensed. 当你传入some_softwarewhich has type时SomeSoftware,Rust 推断它T必须是 type SomeSoftware。但参数software_two也有类型T,即 type SomeSoftware。但是你向它传递了一个类型的参数OtherSoftware。这就是它无法编译的原因。

您可以通过compare_license_types对都实现的两种不同类型进行泛型来解决此问题Licensed

fn compare_license_types<T: Licensed, U: Licensed>(software: T, software_two: U) -> bool { ...
Run Code Online (Sandbox Code Playgroud)

这就是impl Trait语法隐式执行的操作。