rust - ¿Hay alguna forma de crear un alias de tipo para múltiples rasgos?
(2)
Tengo una función genérica que imprime el mínimo de dos elementos:
use std::fmt::Display;
fn print_min<T: PartialOrd + Display>(a: &T, b: &T) {
println!("min = {}", if a < b { a } else { b });
}
Esto funciona bastante bien con cualquier cosa que implemente los rasgos
PartialOrd
y
Display
:
print_min(&45, &46);
// min = 45
print_min(&"a", &"b");
// min = a
Tener que poner el
PartialOrd + Display
en la definición de la función es algo feo, especialmente si quiero tener un montón de funciones que operen en esto (implementando un árbol de búsqueda binario, por ejemplo), o si mis límites se vuelven más complejos.
Mi primera inclinación fue intentar escribir un alias de tipo:
type PartialDisplay = PartialOrd + Display;
pero esto me da algunos errores de compilación bastante extraños:
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
Supongo que mi sintaxis es incorrecta o que esto todavía no es posible. Me gustaría algo como
type PartialDisplay = ???
fn print_min<T: PartialDisplay> { /* ... */ }
RFC 1733 introdujo el concepto de un alias de rasgo . Cuando se estabilice , podrás decir:
#![feature(trait_alias)]
use std::fmt::Display;
trait PartialDisplay<Rhs = Self> = PartialOrd<Rhs> + Display;
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(&"a", &"b");
}
PartialOrd
y
Display
son rasgos.
Se
ha discutido
cómo implementar un alias, pero se decidió que no era necesario.
En su lugar, puede crear un nuevo rasgo con los rasgos que desee como súper rasgos y proporcionar una implementación general:
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");
}