Rust 中 trait 的冲突实现
Conflicting implementations of trait in Rust
我想为 &'a str
和最大 i32
的整数实现自定义特征,但 Rust 不允许我:
use std::convert::Into;
pub trait UiId {
fn push(&self);
}
impl<'a> UiId for &'a str {
fn push(&self) {}
}
impl<T: Into<i32>> UiId for T {
fn push(&self) {}
}
fn main() {}
编译失败,出现以下错误:
error[E0119]: conflicting implementations of trait `UiId` for type `&str`:
--> src/main.rs:11:1
|
7 | impl<'a> UiId for &'a str {
| ------------------------- first implementation here
...
11 | impl<T: Into<i32>> UiId for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&str`
|
= note: upstream crates may add new impl of trait `std::convert::From<&str>` for type `i32` in future versions
&'a str
没有实现 Into<i32>
。是否可以在不指定具体类型的情况下为 &'a str
实现 UiId
以及所有可以转换为 i32
的内容?我该怎么做?
&'a str
没有实现 Into<i32>
的事实没有被考虑在内,因为不能保证以后不会添加它。这会破坏您的代码。
因此,如果允许这样做,可能的破坏将使向库特征添加实现变得更加困难。
不幸的是,我在 The Rust Programming Language Book nor in the Reference Manual.
中找不到相关文档
我能找到的最好的是 RFC 1023,它说 a crate [...] 不能依赖 Type: !Trait
持有,除非 Type
或 Trait
是本地的。
我找到了使用标记特征的解决方法。无需夜间或实验性功能。诀窍是我在我的板条箱中定义了标记特征并且不导出它,所以上游板条箱不可能在 类 上定义标记,而不是我实现它的那些。
标记特征下方是Numeric
.
我使用它是为了我可以为任何可以转换为 f64 的东西实现 Into,也可以为单独的 impl 中的字符串和其他类型实现 Into。
Numeric
特征必须是 pub
因为他们警告说未来的版本将不允许 public 接口中的私有特征。
use std::convert::Into;
pub trait Numeric {}
impl Numeric for f64 {}
impl Numeric for f32 {}
impl Numeric for i64 {}
impl Numeric for i32 {}
impl Numeric for i16 {}
impl Numeric for i8 {}
impl Numeric for isize {}
impl Numeric for u64 {}
impl Numeric for u32 {}
impl Numeric for u16 {}
impl Numeric for u8 {}
impl Numeric for usize {}
pub trait UiId {
fn push(&self);
}
impl<'a> UiId for &'a str {
fn push(&self) {}
}
impl<T: Into<i32> + Numeric> UiId for T {
fn push(&self) {}
}
我想为 &'a str
和最大 i32
的整数实现自定义特征,但 Rust 不允许我:
use std::convert::Into;
pub trait UiId {
fn push(&self);
}
impl<'a> UiId for &'a str {
fn push(&self) {}
}
impl<T: Into<i32>> UiId for T {
fn push(&self) {}
}
fn main() {}
编译失败,出现以下错误:
error[E0119]: conflicting implementations of trait `UiId` for type `&str`:
--> src/main.rs:11:1
|
7 | impl<'a> UiId for &'a str {
| ------------------------- first implementation here
...
11 | impl<T: Into<i32>> UiId for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&str`
|
= note: upstream crates may add new impl of trait `std::convert::From<&str>` for type `i32` in future versions
&'a str
没有实现 Into<i32>
。是否可以在不指定具体类型的情况下为 &'a str
实现 UiId
以及所有可以转换为 i32
的内容?我该怎么做?
&'a str
没有实现 Into<i32>
的事实没有被考虑在内,因为不能保证以后不会添加它。这会破坏您的代码。
因此,如果允许这样做,可能的破坏将使向库特征添加实现变得更加困难。
不幸的是,我在 The Rust Programming Language Book nor in the Reference Manual.
中找不到相关文档我能找到的最好的是 RFC 1023,它说 a crate [...] 不能依赖 Type: !Trait
持有,除非 Type
或 Trait
是本地的。
我找到了使用标记特征的解决方法。无需夜间或实验性功能。诀窍是我在我的板条箱中定义了标记特征并且不导出它,所以上游板条箱不可能在 类 上定义标记,而不是我实现它的那些。
标记特征下方是Numeric
.
我使用它是为了我可以为任何可以转换为 f64 的东西实现 Into,也可以为单独的 impl 中的字符串和其他类型实现 Into。
Numeric
特征必须是 pub
因为他们警告说未来的版本将不允许 public 接口中的私有特征。
use std::convert::Into;
pub trait Numeric {}
impl Numeric for f64 {}
impl Numeric for f32 {}
impl Numeric for i64 {}
impl Numeric for i32 {}
impl Numeric for i16 {}
impl Numeric for i8 {}
impl Numeric for isize {}
impl Numeric for u64 {}
impl Numeric for u32 {}
impl Numeric for u16 {}
impl Numeric for u8 {}
impl Numeric for usize {}
pub trait UiId {
fn push(&self);
}
impl<'a> UiId for &'a str {
fn push(&self) {}
}
impl<T: Into<i32> + Numeric> UiId for T {
fn push(&self) {}
}