相关疑难解决方法(0)

如何在泛型函数中要求泛型类型实现Add,Sub,Mul或Div等操作?

我正在尝试在Rust中实现泛型函数,其中对参数的唯一要求是应该定义乘法运算.我正在尝试实现一个通用的"权力",但将使用更简单的cube功能来说明问题:

use std::ops::Mul;

fn cube<T: Mul>(x: T) -> T {
    x * x * x
}

fn main() {
    println!("5^3 = {}", cube(5));
}
Run Code Online (Sandbox Code Playgroud)

编译时我收到此错误:

error[E0369]: binary operation `*` cannot be applied to type `<T as std::ops::Mul>::Output`
 --> src/main.rs:4:5
  |
4 |     x * x * x
  |     ^^^^^^^^^
  |
  = note: an implementation of `std::ops::Mul` might be missing for `<T as std::ops::Mul>::Output`
Run Code Online (Sandbox Code Playgroud)

这是什么意思?我选择了错误的特质吗?我该如何解决这个问题?

generics rust

21
推荐指数
2
解决办法
3128
查看次数

如何为不同的RHS类型和返回值重载运算符?

给定以下结构:

struct Vector3D {
    x: f32,
    y: f32,
    z: f32
}
Run Code Online (Sandbox Code Playgroud)

*当右边是a时Vector3D,我想重载它的运算符来做一个点积,当RHS是a时,我想重做元素乘法f32.我的代码看起来像这样:

// Multiplication with scalar
impl Mul<f32, Vector3D> for Vector3D {
    fn mul(&self, f: &f32) -> Vector3D {
        Vector3D {x: self.x * *f, y: self.y * *f, z: self.z * *f} 
    }   
}
// Multiplication with vector, aka dot product
impl Mul<Vector3D, f32> for Vector3D {
    fn mul(&self, other: &Vector3D) -> f32 {
        self.x * other.x + self.y * other.y + self.z * other.z …
Run Code Online (Sandbox Code Playgroud)

operator-overloading rust

19
推荐指数
2
解决办法
3421
查看次数

如何在Rust中实现值和引用的惯用运算符重载?

当实现原始固定大小的矢量类型(float2例如)时,我想支持AddSub特征.后来,我想支持Mul*Assign.

查看文档和其他示例,我想出了这个:

use std::ops::{Add, Sub};

#[derive(Copy, Clone)]
struct float2(f64, f64);

impl Add for float2 {
    type Output = float2;
    fn add(self, _rhs: float2) -> float2 {
        float2(self.0 + _rhs.0, self.1 + _rhs.1)
    }
}

impl Sub for float2 {
    type Output = float2;
    fn sub(self, _rhs: float2) -> float2 {
        float2(self.0 - _rhs.0, self.1 - _rhs.1)
    }
}
Run Code Online (Sandbox Code Playgroud)

这适用于基本的例子,但是我在实践中发现我会经常与作为参数传入,以及局部引用最终float2在栈上的.

混合这些我需要:

  • 取消引用变量(好但是使代码的可读性稍差).
  • 声明运算符也会重载引用的组合.

例:

impl<'a, 'b> Add<&'b float2> for …
Run Code Online (Sandbox Code Playgroud)

operator-overloading rust

9
推荐指数
1
解决办法
622
查看次数

重载Add-operator而不复制操作数

我正在Rust中编写一个应用程序,它必须集中使用向量算法,我偶然发现了为结构类型设计运算符重载的问题.

所以我有一个这样的矢量结构:

struct Vector3d {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}
Run Code Online (Sandbox Code Playgroud)

我希望能够写出类似的东西:

let x = Vector3d {x:  1.0, y: 0.0, z: 0.0};
let y = Vector3d {x: -1.0, y: 0.0, z: 0.0};

let u = x + y;
Run Code Online (Sandbox Code Playgroud)

据我所知,有三种不同的方法:

  1. 直接实施std::ops::Add特质Vector3d.这有效,但这个特征的方法签名是:

    fn add(self, other: Vector3d)
    
    Run Code Online (Sandbox Code Playgroud)

所以它会在使用后使它的参数无效(因为它会移动它们),这在我的情况下是不可取的,因为许多矢量将用在多个表达式中.

  1. 实现Add特征Vector3d并实现Copy特征.这是有效的,但我觉得如果因为Vector3d它不是一个轻量级的东西(至少24字节)可以快速复制,特别是当有很多调用算术函数时.

  2. 实现Add对参考文献Vector3d,如建议在这里.这是有效的,但为了应用运算符,我将不得不写

    let u = &x + &y;
    
    Run Code Online (Sandbox Code Playgroud)

我不喜欢这种符号,因为它看起来并不完全像数学等价物u = x + …

rust

5
推荐指数
1
解决办法
348
查看次数

如何为引用类型实现Add,以便我可以一次添加两个以上的值?

我想创建一个不可变的,引用数据类型,并添加如下:

use std::ops::Add;

struct Point {
    x: i64,
    y: i64,
}

impl<'a> Add for &'a Point {
    type Output = Point;
    fn add(self, other: &Point) -> Point {
        Point {
            x: self.x + &other.x,
            y: self.y + &other.y,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何实现添加特征以引用结构?建议Add在引用类型上实现.

我可以做到这一点,在哪里abPoint:

let c = &a + &b;
let d = &c + &b;
Run Code Online (Sandbox Code Playgroud)

但不是这个:

let d = &a + &b + &b;
Run Code Online (Sandbox Code Playgroud)

我不介意这些&迹象,但不能连锁添加对我来说并不好看.我想实现乘法(z = a + …

add rust

2
推荐指数
1
解决办法
171
查看次数

如何在枚举上进行运算符重载?

我有一个枚举:

enum Numbers {
    A = 1,
}
Run Code Online (Sandbox Code Playgroud)

如何重载运算符,以便我可以将Numbers枚举与另一个标准数字进行比较而无需执行此操作as u32?如果我想这样做:

let a = Numbers::A < 4
Run Code Online (Sandbox Code Playgroud)

我想我在某个地方读到了可以用某种宏做的事情?也许有一个箱子可以让我这样做?到目前为止,我唯一能取得成功的是,as u32但每次都必须把它写出来是相当繁琐的.

rust

2
推荐指数
1
解决办法
164
查看次数

为什么需要实现Add以使用特征Num添加两个变量?

我有一个叫做的函数add_vec.它需要两个向量并通过对压缩向量中的元素对执行元素加法来创建一个新向量.

extern crate num;
use num::traits::Num;

fn add_vec<N: Num>(v1s: Vec<N>, v2s: Vec<N>) -> Vec<N> {
    let mut v3s = Vec::new();
    for (v1, v2) in v1s.iter().zip(v2s.iter()) {
        v3s.push(v1 + v2)
    }
    v3s
}

#[cfg(test)]
mod tests {
    use super::add_vec;
    #[test]
    fn it_works() {
        let v1s = vec![1, 0, 3];
        let v2s = vec![0, 1, 1];
        let v3s = add_vec(v1s, v2s);
        assert_eq!(v3s, vec![1, 1, 4]);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我最终得到以下错误消息:

error[E0369]: binary operation `+` cannot be applied to type `&N`
  --> src/lib.rs:14:18 …
Run Code Online (Sandbox Code Playgroud)

generics rust

1
推荐指数
1
解决办法
86
查看次数

如何实现std :: ops:{Add,Sub,Mul,Div}运算符之一而不移出参数?

我正在编写光线追踪器,并且希望能够减去3D向量:

use std::ops::Sub;

#[derive(Clone, Debug)]
pub struct Vec3 {
    pub v: [f64; 3],
}

impl Sub for Vec3 {
    type Output = Vec3;

    fn sub(self, other: Vec3) -> Vec3 {
        Vec3 {
            v: [
                self.v[0] - other.v[0],
                self.v[1] - other.v[1],
                self.v[2] - other.v[2],
            ],
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效。但是,当我尝试使用它时:

fn main() {
    let x = Vec3 { v: [0., 0., 0.] };
    let y = Vec3 { v: [0., 0., 0.] };
    let a = x - y;
    let b = …
Run Code Online (Sandbox Code Playgroud)

rust

1
推荐指数
1
解决办法
363
查看次数

标签 统计

rust ×8

generics ×2

operator-overloading ×2

add ×1