如何在泛型类型中使用`Num :: one()`?

时间:2015-02-02 19:17:53

标签: rust

我正在尝试实现通用向量的normalize功能,这要求我使用等同于self.mulf(1.0 / self.length())的内容。

然而,我无法一般性地指出我需要的一个'使用Float::one()的任何可能类型的浮点数。

如果在泛型函数中使用,后者可以正常工作,但不能在通用类型中使用。

如何在通用类型中使用Num::one()

守则

以下代码应作为示例来展示我已经尝试过的内容。此外,我相信已经看到在通用特征实现中使用Float::one()的代码,但我不想要特质化'我的载体让它尽可能简单。

use std::num::Float;

#[derive(Debug, PartialEq, Eq, Copy)]
pub struct Vector<T: Float> {
    x: T,
    y: T,
    z: T,
}

impl<T: Float> Vector<T> {
    #[inline(always)]
    fn mulfed(&self, m: T) -> Vector<T> {
        Vector { x: self.x * m, y: self.y * m, z: self.z * m }
    }

    fn dot(&self, r: &Vector<T>) -> T {
        self.x * r.x + self.y * r.y + self.z * r.z
    }

    // "the type of this value must be known in this context"
    // fn normalized(&self) -> Vector<T> {
    //     self.mulfed(Float::one() / self.dot(self).sqrt())
    // }
    // "the type of this value must be known in this context"
    // fn normalized(&self) -> Vector<T> {
    //     self.mulfed(Float::one() as T / self.dot(self).sqrt())
    // }

    // "too many type parameters provided: expected at most 0 parameter(s), found 1 parameter(s)"
    // As Float is a trait, this can be expected to not work I guess. It should be able to 
    // use Float::one() from within another trait though.
    // fn normalized(&self) -> Vector<T> {
    //     self.mulfed(Float::one::<T>() / self.dot(self).sqrt())
    // }
}

fn gimme_one<T: Float>() -> T {
    Float::one()
}

#[test]
fn one() {
    // But this works !!
    let v: f32 = gimme_one();
    assert_eq!(v, 1.0f32);
}

我正在使用rustc 1.0.0-nightly (458a6a2f6 2015-01-25 21:20:37 +0000)

1 个答案:

答案 0 :(得分:1)

这是bug in type inference。在修复错误之前,您可以使用完全指定的UFCS表单:

fn normalized(&self) -> Vector<T> {
    self.mulfed(<T as Float>::one() / self.dot(self).sqrt())
}

更好的是,您可以使用Float::recip

fn normalized(&self) -> Vector<T> {
    self.mulfed(self.dot(self).sqrt().recip())
}