pub fn blanket_impls()
Expand description
§Overlapping blanket impls
当前 Rust 不支持 trait
为 同一个类型覆盖实现:
trait Blanket {
fn blanket(&self) -> &'static str;
}
impl Blanket for u8 {
fn blanket(&self) -> &'static str {
"impl1"
}
}
// Compilation fails at that point
impl Blanket for u8 {
fn blanket(&self) -> &'static str {
"impl2"
}
}
fn main() {
// If compilation succeeded, what would be printed?
println!("{}", 0u8.blanket());
}
再比如泛型:
impl <T: ToString> Blanket for T { ... }
// Compilation fails at that point
impl <T: Clone> Blanket for T { ...}
以上是 Rust 不允许的。
虽然特化功能也逐渐开始支持,但不足以解决上面这种存在trait
实现“竞争”的情况。
一个解决方案是:
trait Blanket<I> {
fn blanket(&self) -> &'static str;
}
impl Blanket<u8> for u8 {
fn blanket(&self) -> &'static str {
"u8"
}
}
impl<T: ToString> Blanket<&ToString> for T {
fn blanket(&self) -> &'static str {
"ToString"
}
}
trait CloneBlanket {}
impl<T: Clone> Blanket<&CloneBlanket> for T {
fn blanket(&self) -> &'static str {
"Clone"
}
}
trait TryIntoBlanket<T> {
type Error;
}
impl<T, E, U> Blanket<&TryIntoBlanket<T, Error = E>> for U
where
U: TryInto<T, Error = E>,
{
fn blanket(&self) -> &'static str {
"try_into"
}
}
impl<T: ToString> Blanket<&ToString> for T {
fn blanket(&self) -> &'static str {
"to_string"
}
}
impl<T: AsRef<U>, U: ?Sized> Blanket<&AsRef<U>> for T {
fn blanket(&self) -> &'static str {
"as_ref"
}
}
方案参考:https://codesandwich.github.io/overlapping_blanket_impls/