В примере проекта Rust я создал функцию, которая сравнивает два значения типов, реализующих признак PartialOrd
, но не компилируется:
fn main(){
let x: i32 = 5;
let y: i32 = 6;
dbg!(greater_than(&x, &y));
}
fn greater_than(x: &impl PartialOrd, y: &impl PartialOrd) -> bool{
x > y
}
error[E0308]: mismatched types
--> src/main.rs:8:9
|
7 | fn greater_than(x: &impl PartialOrd, y: &impl PartialOrd) -> bool{
| --------------- --------------- found type parameter
| |
| expected type parameter
8 | x > y
| ^ expected type parameter `impl PartialOrd`, found a different type parameter `impl PartialOrd`
|
= note: expected reference `&impl PartialOrd` (type parameter `impl PartialOrd`)
found reference `&impl PartialOrd` (type parameter `impl PartialOrd`)
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
Насколько я понимаю, как только ваши параметры в сигнатуре вашей функции были набраны с использованием синтаксиса признака impl, любой тип, реализующий этот признак (i32 предназначен для реализации признака PartialOrd), может использоваться в функции в качестве аргумента. (Я использовал другую сигнатуру функции, используя границы свойств, как показано ниже, и она работала нормально):
fn greater_than<T: PartialOrd>(x: &T, y: &T) -> bool
Каждое появление impl Trait
дает новый отдельный параметр типа. Например, x
может быть u32
и y
String
. Оба реализуют PartialOrd
, но их все равно нельзя сравнивать друг с другом.
То, что вы хотите, не может быть выражено с помощью impl Trait
, так как вам нужно указать тип дважды:
fn greater_than<T: PartialOrd>(x: &T, y: &T) -> bool{
x > y
}
Или принять даже два разных типа, если их можно сравнивать:
fn greater_than<T: PartialOrd<U>, U>(x: &T, y: &U) -> bool {
x > y
}
Насколько я понимаю, как только ваши параметры в сигнатуре вашей функции были набраны с использованием синтаксиса признака impl, любой тип, реализующий этот признак (i32 предназначен для реализации признака PartialOrd), может использоваться в функции в качестве аргумента.
Ну да, но impl trait
не определяет никакой связи между вашими аргументами, поэтому то, что вы написали, по сути,
fn greater_than<T: PartialOrd, U: PartialOrd>(x: &T, y: &U) -> bool
Таким образом, каждый аргумент частично сопоставим сам с собой, но из этого не следует, что они частично сопоставимы друг с другом. Что касается Rust, вы можете передать i32 в качестве первого параметра и строку в качестве второго, оба impl PartialOrd
.