简体   繁体   English

Rustlings traits4.rs 为什么 impl Trait 语法有效但 trait bound 语法或 where 子句不起作用

[英]Rustlings traits4.rs Why impl Trait syntax works but trait bound syntax or where clause does not work

I'm doing Rustlings course traits4.rs exercise.我正在做 Rustlings 课程的 traits4.rs 练习。 The task is basically choose the correct signature for compare_license_types function.任务基本上是为compare_license_types function 选择正确的签名。 Using the impl Trait syntax as below works well:使用下面的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));
    }
}

If I change the function signature to use trait bound syntax or where clause, it no longer compiles:如果我将 function 签名更改为使用特征绑定语法或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 {}

Both fail with compile error:两者都因编译错误而失败:

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`

What am I missing here?我在这里想念什么?

fn compare_license_types<T: Licensed>(software: T, software_two: T) -> bool { ...

tells the compiler that both software and software_two have type T , where T can be any type implementing Licensed .告诉编译器softwaresoftware_two都有类型T ,其中T可以是实现Licensed的任何类型。 When you pass in some_software which has type SomeSoftware , Rust infers that T must be type SomeSoftware .当您传入具有some_software类型的SomeSoftware时,Rust 推断T必须是SomeSoftware类型。 But the parameter software_two also has type T , ie type SomeSoftware .但是参数software_two也有类型T ,即类型SomeSoftware But you're passing it an argument of type OtherSoftware .但是你传递给它类型为OtherSoftware的参数。 That's why it doesn't compile.这就是它不编译的原因。

You can fix this by making compare_license_types generic over two distinct types that both implement Licensed :您可以通过使compare_license_types对两个都实现了Licensed的不同类型通用来解决此问题:

fn compare_license_types<T: Licensed, U: Licensed>(software: T, software_two: U) -> bool { ...

which is what the impl Trait syntax does implicitly.这就是impl Trait语法隐含的作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM