Есть ли способ создать псевдоним типа для нескольких признаков?
У меня есть общая функция, которая печатает минимум два элемента:
use std::fmt::Display;
fn print_min<T: PartialOrd + Display>(a: &T, b: &T) {
println!("min = {}", if a < b { a } else { b });
}
Это работает очень хорошо со всем, что реализует как PartialOrd
а также Display
черты:
print_min(&45, &46);
// min = 45
print_min(&"a", &"b");
// min = a
Должен поставить PartialOrd + Display
в определении функции это выглядит некрасиво, особенно если я хочу иметь целый набор функций, которые работают с этим (например, реализуя двоичное дерево поиска), или если мои границы становятся более сложными. Первым делом я попытался написать псевдоним типа:
type PartialDisplay = PartialOrd + Display;
но это дает мне довольно странные ошибки компилятора:
error[E0393]: the type parameter `Rhs` must be explicitly specified
--> src/main.rs:7:23
|
7 | type PartialDisplay = PartialOrd + Display;
| ^^^^^^^^^^ missing reference to `Rhs`
|
= note: because of the default `Self` reference, type parameters must be specified on object types
error[E0225]: only auto traits can be used as additional traits in a trait object
--> src/main.rs:7:36
|
7 | type PartialDisplay = PartialOrd + Display;
| ^^^^^^^ non-auto additional trait
Я предполагаю, что либо мой синтаксис неправильный, либо это просто невозможно. Я хотел бы что-то вроде
type PartialDisplay = ???
fn print_min<T: PartialDisplay> { /* ... */ }
3 ответа
PartialOrd
а также Display
это черты. Обсуждали, как реализовать псевдоним, но было решено, что он не нужен.
Вместо этого вы можете создать новую черту с теми чертами, которые вы хотите использовать как супер-черты, и обеспечить полную реализацию:
use std::fmt::Display;
trait PartialDisplay: PartialOrd + Display {}
impl<T: PartialOrd + Display> PartialDisplay for T {}
fn print_min<T: PartialDisplay>(a: &T, b: &T) {
println!("min = {}", if a < b { a } else { b });
}
fn main() {
print_min(&45, &46);
print_min(&"aa", &"bb");
}
RFC 1733 ввел понятие псевдонима черты. Когда это будет реализовано, вы сможете сказать:
trait PartialDisplay = PartialOrd + Display;
В ожидании стабилизации алиасинга трейтов вы можете использовать набор трейтов. Вот пример его использования:
trait-set! {
pub trait HashKey = Hash + Eq + Clone
}