如何为通用类型实现特质?

3
在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 上定义的。实际上,你唯一的选择是放弃尝试泛型化并声明实际类型。特别是因为没有测试要求你使用泛型。 - Ivan C
1个回答

3
您可以将get_magnitude()限制为仅在适用T时工作。而不是限制T具有powi(),我建议最初将它们转换为f64,然后从那里进行数学计算。
您可以使用来自num创建的AsPrimitive<f64>特征:
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的题目,使用“num”可能不是一个选项。 - Ivan C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接