我写了一个类型 Wrapper<T>
其中包含值 T
:
struct Wrapper<T>(T);
我想要一个方法to_wrap
这将允许我编写这样的代码,其中 b
是Wrapper<i32>
和 c
是Wrapper<i32>
:
let a = 12i32;
let b = a.to_wrap();
let c = b.to_wrap();
我要v.to_wrap()
总是产生一个Wrapper<T>
其中 T 是 NOT a Wrapper
.如果v
是 Wrapper<T>
, v.to_wrap()
也将是一个 Wrapper<T>
具有相同的值。
我写的最接近我想法的代码是:
#![feature(specialization)]
#[derive(Debug)]
struct Wrapper<T>(T);
trait ToWrapper<W> {
fn to_wrap(self) -> W;
}
impl<T> ToWrapper<Wrapper<T>> for T {
default fn to_wrap(self) -> Wrapper<T> {
Wrapper(self)
}
}
impl<T> ToWrapper<Wrapper<T>> for Wrapper<T> {
fn to_wrap(self) -> Self {
self
}
}
fn main() {
let a = 1i32;
println!("{:?}", a);
let a = 1.to_wrap();
println!("{:?}", a);
let a: Wrapper<i32> = 1.to_wrap().to_wrap();
// let a = 1.to_wrap().to_wrap();
// boom with `cannot infer type`
println!("{:?}", a);
}
如果我从 let a: Wrapper<i32> = 1.to_wrap().to_wrap()
上删除类型注释,则会出现编译错误:
error[E0282]: type annotations needed
--> src/main.rs:27:9
|
27 | let a = 1.to_wrap().to_wrap();
| ^
| |
| cannot infer type
| consider giving `a` a type
我希望 Rust 编译器自动导出 1.to_wrap().to_wrap()
的类型.怎么才能写出正确的版本,或者为什么写不出来?
最佳答案
我认为此时您无法通过特化实现实现单一特征的目标。
您的特征定义允许同一类型的特征的多个实现:
trait ToWrapper<W> {
fn to_wrap(self) -> W;
}
impl ToWrapper<i32> for u8 {
fn to_wrap(self) -> i32 {
i32::from(self)
}
}
impl ToWrapper<i16> for u8 {
fn to_wrap(self) -> i16 {
i16::from(self)
}
}
使用这样的设置,不可能知道 to_wrap
应该 的结果类型是什么;您将始终需要以某种方式提供输出类型。然后,您尝试在未知类型上调用 to_wrap
,这将产生另一个未知类型,从而使问题更加复杂!
通常,使用关联类型是解决方案,但由于它们与特化的交互方式,您不能在此处切换到这些类型。
另见:
关于rust - 我如何编写一个方法来包装我的类型中的任何值,可以多次调用而不需要类型注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55455965/