【问题标题】:How to implement a trait for generic type?如何实现泛型类型的特征?
【发布时间】:2021-07-02 18:58:50
【问题描述】:

在 Rust 中,为泛型​​类型实现特征的正确方法是什么?我希望我的向量由整数或浮点数组成。无论我希望 get_magnitude() 输出 f64 的类型如何。如何让 powi() 和 sqrt() 工作?任何解决方法?我卡住了

pub struct Vector<T> {
    i: T,
    j: T,
    k: T,
}

impl<T> Vector<T> {
    fn new(i: T, j: T, k: T) -> Vector<T> {
        Vector {
            i,
            j,
            k,
        }
    }
}

impl<T> Vector<T> {
    fn get_magnitude(&self) -> f64 {
        (self.i.powi(2) + self.j.powi(2) + self.k.powi(2)).sqrt()
    }
}

[https://www.codewars.com/kata/58ee4962dc4f81d6f400001c/rust][1]

【问题讨论】:

  • 标准库中唯一返回f64powi定义在f64上。实际上,您唯一的选择是放弃尝试成为泛型并声明实际类型。特别是因为没有测试要求你是通用的。

标签: generics methods rust traits implementation


【解决方案1】:

您可以将get_magnitide() 限制为仅在T 适用时才起作用。而不是限制T 有一个powi(),我建议最初将它们转换为f64 并从那里进行数学运算。

你可以使用num crate 中的AsPrimitive&lt;f64&gt; trait:

use num::cast::AsPrimitive; // 0.4.0

pub struct Vector<T> {
    i: T,
    j: T,
    k: T,
}

impl<T> Vector<T> {
    fn new(i: T, j: T, k: T) -> Vector<T> {
        Vector { i, j, k }
    }
}

impl<T> Vector<T> {
    fn get_magnitude(&self) -> f64
    where
        T: AsPrimitive<f64>,
    {
        (self.i.as_().powi(2) + self.j.as_().powi(2) + self.k.as_().powi(2)).sqrt()
    }
}

您还可以通过 Num 特征将整个 Vector 结构限制为仅在 T 是数字时才起作用:

use num::Num; // 0.4.0

pub struct Vector<T>
where
    T: Num
{
    i: T,
    j: T,
    k: T,
}

但是您仍然需要对 get_magnitude() 的约束,因为您强制要求它返回 f64

【讨论】:

  • 鉴于这是一个 codewars kata,使用 num 可能不是一个选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
相关资源
最近更新 更多