rust - 我如何编写一个方法来包装我的类型中的任何值,可以多次调用而不需要类型注释?

标签 rust

我写了一个类型 Wrapper<T>其中包含值 T :

struct Wrapper<T>(T);

我想要一个方法to_wrap这将允许我编写这样的代码,其中 bWrapper<i32>cWrapper<i32> :

let a = 12i32;
let b = a.to_wrap();
let c = b.to_wrap();

我要v.to_wrap()总是产生一个Wrapper<T>其中 T 是 NOT a Wrapper .如果vWrapper<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);
}

Playground

如果我从 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/

相关文章:

c++ - 如何从 stdin 读取多行直到 EOF?

rust - 如何确定目标平台而非主机平台在 build.rs 时的 c_uint 大小?

rust - 有没有一种方法可以禁用/启用println!巨集

rust - 来自Struct示例的Serde JSON无法正常工作

rust - 如何使用前缀键搜索获得排序的键值映射?

struct - Rust 中结构的字段可变性

rust - 根据条件如何将输出分配给变量匹配类型

rust - 是否可以在不使用 unsafe 或 panicing 的情况下将潜在未初始化的变量标记为良好?

rust - 将 (T, ()) 转换为 T 安全吗?

容器对象的 Rust 模式