gpt4 book ai didi

generics - 在 Rust 中将 const 除以泛型

转载 作者:行者123 更新时间:2023-11-29 07:46:54 24 4
gpt4 key购买 nike

我有一个结构 Vec3<T> ,如何实现以下方法?

impl<T: num::Num + num::Float> Not<Vec3<T>> for Vec3<T> {
fn not(&self) -> Vec3<T> {
*self * (1.0 / (*self % *self).sqrt())
}
}

错误:类型不匹配:预期 _ , 发现 T (期望浮点变量,找到类型参数)

1.0 的类型是_(*self % *self).sqrt() 的类型是T .而且它似乎不能将 _ 除以 T。

我尝试了 1.0 的各种转换:

*self * ((1.0 as T) / (*self % *self).sqrt())

错误:非标量转换:_作为T

*self * (1.0.div((*self % *self).sqrt()))

错误:类型不匹配:预期 &_ , 发现 T (预期 &-ptr,找到类型参数)

实现此方法最流畅的方法是什么?

编辑 1:根据要求,这是我的完整代码:

use std::num::Float;

pub struct Vec3<T> {
pub x: T,
pub y: T,
pub z: T,
}

impl<T> Vec3<T> {
pub fn new(x: T, y: T, z: T) -> Vec3<T> {
Vec3 { x: x, y: y, z: z }
}
}

impl<T: Float> Add<T, Vec3<T>> for Vec3<T> {
fn add(&self, rhs: &T) -> Vec3<T> {
Vec3 { x: self.x + *rhs, y: self.y + *rhs, z: self.z + *rhs }
}
}

impl<T: Float> Add<Vec3<T>, Vec3<T>> for Vec3<T> {
fn add(&self, rhs: &Vec3<T>) -> Vec3<T> {
Vec3 { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z }
}
}

impl<T: Float> Mul<T, Vec3<T>> for Vec3<T> {
fn mul(&self, rhs: &T) -> Vec3<T> {
Vec3 { x: self.x * *rhs, y: self.y * *rhs, z: self.z * *rhs }
}
}

// x % y : dot-product
impl<T: Float> Rem<Vec3<T>, T> for Vec3<T> {
fn rem(&self, rhs: &Vec3<T>) -> T {
self.x + rhs.x * self.y + rhs.y * self.z + rhs.z
}
}

// x ^ y : cross-product
impl<T: Float> BitXor<Vec3<T>, Vec3<T>> for Vec3<T> {
fn bitxor(&self, rhs: &Vec3<T>) -> Vec3<T> {
Vec3 { x: self.y * rhs.z - self.z * rhs.y,
y: self.z * rhs.x - self.x * rhs.z,
z: self.x * rhs.y - self.y * rhs.x }
}
}

// !x : Norm
impl Not<Vec3<f32>> for Vec3<f32> {
fn not(&self) -> Vec3<f32> {
*self * (1.0f32 / (*self % *self).sqrt())
}
}

impl Not<Vec3<f64>> for Vec3<f64> {
fn not(&self) -> Vec3<f64> {
*self * (1.0f64 / (*self % *self).sqrt())
}
}

我会使用 Num而不是 Float能够拥有整数向量,但由于它已被弃用,我认为更好的选择是使用宏来复制所有类型的代码。在这里我复制了 Not对于 f32f64

最佳答案

文字只能是原始类型。您不能将文字转换为某种泛型类型。

对于像 1.0 这样的常量,你可以使用像 Float::one() 这样的方法, 所以你的具体例子可以重写为

impl<T: num::Float> Not<Vec3<T>> for Vec3<T> {
fn not(&self) -> Vec3<T> {
*self * (num::Float::one() / (*self % *self).sqrt())
}
}

(请注意,我删除了 Num 绑定(bind),因为它已被弃用,在这种情况下它完全被 Float 取代)

要将任意值转换为某些特定 Float 类型的实例,您可以使用 NumCast::from()方法:

let x: T = num::NumCast::from(3.14f64);

顺便说一句,你可能会找到this accepted RFC有趣。

更新

您很可能无法为您的结构实现 Float,因为它有很多特定于裸 float 的方法,例如尾数大小。我想您将不得不添加 one()zero() 之类的方法,并且可能需要自己从数字中转换。然后你就可以写了

impl<T: num::Float> Not<Vec3<T>> for Vec3<T> {
fn not(&self) -> Vec3<T> {
*self * (Vec3::one() / (*self % *self).sqrt())
}
}

关于generics - 在 Rust 中将 const 除以泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27441224/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com