【问题标题】:How to convert generic primitive types in Rust? [duplicate]如何在 Rust 中转换泛型原始类型? [复制]
【发布时间】:2019-04-26 12:11:47
【问题描述】:

我想写如下内容:

pub struct Point<T> {
    pub x: T,
    pub y: T,
}

impl<T> Point<T> {
    pub fn from<U>(other: Point<U>) -> Point<T> {
        Point {
            x: other.x as T,
            y: other as T,
        }
    }
}

这是不可能的:

error[E0605]: non-primitive cast: `U` as `T`
 --> src/lib.rs:9:16
  |
9 |             x: other.x as T,
  |                ^^^^^^^^^^^^
  |
  = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait

查看How do I cast generic T to f32 if I know that it's possible?,我了解到From trait 不适用于i32f32 的转换,这正是我最初想要的。

我能想出的最简单的解决方案是编写如下函数:

pub fn float2_from_int2(v: Point<i32>) -> Point<f32> {
   Point::<f32>::new(v.x as f32, v.y as f32)
}

显然,Rust 从i32 转换为f32 没有问题。有没有更好的写法?

【问题讨论】:

  • 注意你应该带self,这样更有意义
  • 您能详细说明一下吗?我还没有self,因为我刚要创建Point&lt;T&gt;。因此from&lt;U&gt;,可以说是构造函数。
  • 我不建议您实施 From 有一个原因是没有 From&lt;i32&gt; for f32 实施,也许这样做,play.integer32.com/…,但请注意,就像我的示例节目一样,这可能会导致奇怪的行为。

标签: generics casting rust


【解决方案1】:

你可以使用来自numToPrimitive trait
示例(您可以避免使用 AsPrimitive 的 Option):

pub struct Point<T> {
    pub x: T,
    pub y: T,
}

impl<T: Copy + 'static> Point<T> {
    pub fn from<U: num::cast::AsPrimitive<T>>(other: Point<U>) -> Point<T> {
        Point {
            x: other.x.as_(),
            y: other.y.as_(),
        }
    }
}

fn do_stuff() {
    let a = Point{x: 0i32, y: 0i32};
    let b = Point::<f32>::from(a);
}

【讨论】:

  • 特征NumCastToPrimitive 中的方法返回Option,因为给定值可能无法在目标类型中表示(例如,您不能将256 保存在@ 987654328@)。这些确实使用起来更安全,因为它们可以避免奇怪的情况。 AsPrimitive 忽略了这一点,因此其行为与 as 运算符完全相同。
  • 也许实现新稳定的TryFrom trait 是处理Optional 结果的好方法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-17
  • 2018-06-12
  • 2019-09-28
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
相关资源
最近更新 更多