我想实现这个Shl特性Vec,代码如下.这会使事情变得vec << 4可能,这对于它来说是个不错的选择vec.push(4).
use std::ops::Shl;
impl<T> Shl<T> for Vec<T> {
type Output = Vec<T>;
fn shl(&self, elem: &T) -> Vec<T> {
self.push(*elem);
*self
}
}
fn main() {
let v = vec![1, 2, 3];
v << 4;
}
Run Code Online (Sandbox Code Playgroud)
编译失败,出现以下错误:
无法提供扩展实现,其中特征和类型都未在此包中定义[E0117]
要么
type参数
T必须用作某些本地类型的类型参数(例如MyStruct<T>); 只有当前包中定义的特征才能为类型参数实现[E0210]
据我了解,我必须修补stdlib,更具体地来说是collections::vec板条箱.有没有其他方法可以更改此代码以成功编译?
Luq*_*man 35
虽然你不能完全这样做,但通常的解决方法是在你自己的类型中包装你想要的类型并在其上实现特征.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}
Run Code Online (Sandbox Code Playgroud)
mal*_*rbo 12
这会使事情变得
vec << 4可能,这对于它来说是个不错的选择vec.push(4).
尽管可以这样做,但实现具有意外语义的运算符通常是一个坏主意.
以下是如何完成此操作的示例:
use std::ops::Shl;
struct BadVec<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
fn shl(mut self, elem: T) -> Self::Output {
self.0.push(elem);
self
}
}
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
assert_eq!(vec![1, 2, 3, 4], v.0)
}
Run Code Online (Sandbox Code Playgroud)
use std::ops::{Deref, DerefMut};
impl<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
Run Code Online (Sandbox Code Playgroud)
你可以调用Vec方法:
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
v.truncate(2);
assert_eq!(2, v.len());
}
Run Code Online (Sandbox Code Playgroud)
看看newtype_derive箱子,它可以为你生成一些样板代码.
snn*_*snn 11
这是有意禁止的,被称为“孤儿规则”。这是为了保证特质的一致性。根据孤儿规则,除非您是定义该结构的板条箱,或者是定义该特征的板条箱,否则您不能为结构提供特征的实现。如果你能实现你所要求的,我们就会有相互冲突的实现。
不过有一些解决方法,最常见的一种是新类型模式。在 newtype 模式中,我们将外部类型包装在本地结构中,并通过这个包装器实现所需的方法。
// External struct
use foo::Foo;
// Create a new type.
pub struct Bar(Foo);
// Provide your own implementations
impl Bar {
pub fn new() -> Self {
//..
}
}
Run Code Online (Sandbox Code Playgroud)
欲了解更多信息,请查看这些参考资料:
| 归档时间: |
|
| 查看次数: |
3230 次 |
| 最近记录: |