简体   繁体   English

Rust 中 arrays 的加法重载

[英]Overloading of addition for arrays in Rust

Trying to sum two arrays ( [1.0, 2.0] + [3.0, 4.0] ) fails in Rust as addition isn't defined for arrays.尝试在 Rust 中对两个 arrays ( [1.0, 2.0] + [3.0, 4.0] ) 求和失败,因为没有为 ZA3CBC3F9D0CE2F2C1554E1B671DCZ1 定义加法。 I tried to overload the operation:我试图重载操作:

use std::ops::Add;
type float = f64;
impl<const N: usize> Add for [float;N] {
    type Output = Self;
    fn add(x : [float; N], y : [float; N]) {
        let z : [float; N];
        for i in 1..=N { z[i] = x[i] + y[i]; }
        z
    }
}

However, now rustc says that this is disallowed: “ only traits defined in the current crate can be implemented for arbitrary types ”.然而,现在 rustc 表示这是不允许的:“只有当前 crate 中定义的特征才能用于任意类型”。 Rust also doesn't allow defining custom operators, such as .+ or so for elementwise addition. Rust 也不允许定义自定义运算符,例如.+左右元素相加。

Why would I want such a thing?为什么我会想要这样的东西? I'm looking at using Rust for numerical computing, having gotten fed up with the dynamic typing of Julia, and resulting wasted hours trying to get hidden memory allocations down when it fails to specialise functions.我正在考虑使用 Rust 进行数值计算,已经厌倦了 Julia 的动态类型,结果浪费了数小时试图隐藏 memory 分配功能失败。 However, requiring custom types and boilerplate code to sum two arrays doesn't seem very practical.但是,要求自定义类型和样板代码将两个 arrays 相加似乎不太实用。 For big arrays one of course wants to use something else;对于大 arrays,当然想用别的东西; there's ndarray , but based on just having tried to wrap it into a general LinearOperator trait, it seems to have its own problems due to lack of an AbstractArray trait or enum to cover both concrete arrays and views, and somewhat weird rhs-only lifetimes (although the latter might also be just me just trying to learn lifetimes).ndarray ,但基于只是试图将其包装成一般的LinearOperator特征,由于缺少AbstractArray特征或枚举来涵盖具体的 arrays 和视图,它似乎有自己的问题,以及有点奇怪的 rhs-only 生命周期(虽然后者也可能只是我只是想学习生命)。 But such a thing is neither feasible nor efficient for simple small and fast “inner loop” computations that occur here and there.但是对于到处发生的简单的小而快速的“内循环”计算来说,这样的事情既不可行也不高效。 On the other hand, having to use ascii-literal functions for standard mathematical operations also does not help readability.另一方面,必须使用 ascii-literal 函数进行标准数学运算也无助于可读性。

Any ideas?有任何想法吗? Any future hope of getting custom (unicode) operators or at least being able to locally overload the standard ones?未来是否有希望获得自定义(unicode)运算符或至少能够在本地重载标准运算符? (If somebody wants to complain about users potentially defining meaningless unreadable operators, I can say the same about bitwise operators. Seriously, in 2021, you put those in the language itself???) (如果有人想抱怨用户可能定义了无意义的不可读运算符,我可以对按位运算符说同样的话。说真的,在 2021 年,你把它们放在语言本身中???)

You can't implement someone else's trait for someone else's type.您不能为其他人的类型实现其他人的特征。 This is to prevent conflicting definitions.这是为了防止定义冲突。 What if you and I BOTH write a crate that defines addition for vec, and someone else uses both the crates?如果你和我都写了一个为 vec 定义加法的板条箱,而其他人同时使用这两个板条箱怎么办? Whose implementation should be used?应该使用谁的实现?

What you can do is wrap vec in your own type and define Add for that type.您可以做的是将 vec 包装在您自己的类型中并为该类型定义 Add 。

struct MyVec<T> { 
  fn new(from: Vec<T>) { ...
}
impl Add for MyVec { ... }

If you want to make access to the underlying Vec transparent (like it is for Box Arc Mutex etc.) you can impl deref for your type.如果您想使对底层 Vec 的访问透明(例如 Box Arc Mutex 等),您可以为您的类型实现 deref。

Something like this will allow you to easily call all the vec methods on your new type.这样的事情将允许您轻松调用新类型的所有 vec 方法。

use std::ops::Deref;

struct MyVec<T> {
    value: T
}
impl<T> Deref for MyVec<T> {
    type Target = Vec<T>;

    fn deref(&self) -> &Self::Target {
        &self.value
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM