繁体   English   中英

如何在 Rust 中实现 abs function 到自定义类型?

[英]How do I implement abs function to custom type in Rust?

我目前正在使用 Rust 编写数字代码。 所以我自己为它创建了一个类型。 此 trait 是一种允许 rust_ndarray 在 f64 和 f32 上执行计算的数据方式。 为了使其成为多线程,我们将 Sync 和 Send 添加到 trait 的边界。 如何在其他 integer 类型中找到我自己的类型中实现 function?

use ndarray_linalg::lapack::Lapack;
use ndarray_linalg::types::Scalar;
use ndarray_linalg::rand_distr::Float;
use std::marker::{Sync, Send};

pub trait Type: Lapack + Scalar + Float + Sync + Send {}

impl Type for f32 {}
impl Type for f64 {}

我想写我自己的 function 来找到这个类型的绝对值。 我该如何实施? 我做了如下所示的实现并得到以下错误。

impl Type {
    pub fn abs(&self) -> Self {
        if self.0 > 0. {self.0}
        else {-1. * self.0}
    }
}

我收到以下错误。 鉴于我收到的错误,我在 Type.xml 中使用的特征边界似乎存在问题。 我还尝试在 trate 边界中包含 ParticalOrd 和 ParticalEq 并收到相同的错误。

note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
    |
   ::: src/traits.rs:7:11
    |
7   | pub trait Type: Lapack + Scalar + Float + Sync + Send {}
    |           ------- this trait cannot be made into an object...
   --> /Users/~~/.cargo/registry/src/github.com-1ecc6299db9ec823/rand_distr-0.2.2/src/utils.rs:24:33
    |
24  | pub trait Float: Copy + Sized + cmp::PartialOrd
    |                                 ^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
25  |     + ops::Neg<Output = Self>
26  |     + ops::Add<Output = Self>
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |       |        |
    |       |        ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
27  |     + ops::Sub<Output = Self>
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |       |        |
    |       |        ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
28  |     + ops::Mul<Output = Self>
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |       |        |
    |       |        ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
29  |     + ops::Div<Output = Self>
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |       |        |
    |       |        ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
30  |     + ops::AddAssign + ops::SubAssign + ops::MulAssign + ops::DivAssign
    |       ^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
    |       |                |                |
    |       |                |                ...because it uses `Self` as a type parameter
    |       |                ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
    |
   ::: /Users/~~/.cargo/registry/src/github.com-1ecc6299db9ec823/cauchy-0.2.2/src/lib.rs:44:7
    |
44  |     + Sum
    |       ^^^ ...because it uses `Self` as a type parameter
45  |     + Product
    |       ^^^^^^^ ...because it uses `Self` as a type parameter
    |
   ::: /Users/~~/.cargo/registry/src/github.com-1ecc6299db9ec823/num-traits-0.2.14/src/lib.rs:67:41
    |
67  | pub trait Num: PartialEq + Zero + One + NumOps {
    |                ^^^^^^^^^                ^^^^^^ ...because it uses `Self` as a type parameter
    |                |
    |                ...because it uses `Self` as a type parameter
...
149 | pub trait NumAssign: Num + NumAssignOps {}
    |                            ^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
    |
   ::: /Users/~~/.cargo/registry/src/github.com-1ecc6299db9ec823/num-traits-0.2.14/src/identities.rs:12:25
    |
12  | pub trait Zero: Sized + Add<Self, Output = Self> {
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^
    |                         |         |
    |                         |         ...because it uses `Self` as a type parameter
    |                         ...because it uses `Self` as a type parameter
...
90  | pub trait One: Sized + Mul<Self, Output = Self> {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^
    |                        |         |
    |                        |         ...because it uses `Self` as a type parameter
    |                        ...because it uses `Self` as a type parameter

error[E0038]: the trait `Type` cannot be made into an object
   --> src/traits.rs:13:6



13  | impl Type {
    |      ^^^^^^^ `Type` cannot be made into an object
    |
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
    |
   ::: src/traits.rs:7:11
    |
7   | pub trait Type: Lapack + Scalar + Float + Sync + Send {}
    |           ------- this trait cannot be made into an object...
   --> /Users/~~/.cargo/registry/src/github.com-1ecc6299db9ec823/rand_distr-0.2.2/src/utils.rs:24:33
    |
24  | pub trait Float: Copy + Sized + cmp::PartialOrd
    |                                 ^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
25  |     + ops::Neg<Output = Self>
26  |     + ops::Add<Output = Self>
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |       |        |
    |       |        ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
27  |     + ops::Sub<Output = Self>
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |       |        |
    |       |        ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
28  |     + ops::Mul<Output = Self>
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |       |        |
    |       |        ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
29  |     + ops::Div<Output = Self>
    |       ^^^^^^^^^^^^^^^^^^^^^^^
    |       |        |
    |       |        ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
30  |     + ops::AddAssign + ops::SubAssign + ops::MulAssign + ops::DivAssign
    |       ^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
    |       |                |                |
    |       |                |                ...because it uses `Self` as a type parameter
    |       |                ...because it uses `Self` as a type parameter
    |       ...because it uses `Self` as a type parameter
    |
   ::: /Users/~~/.cargo/registry/src/github.com-1ecc6299db9ec823/cauchy-0.2.2/src/lib.rs:44:7
    |
44  |     + Sum
    |       ^^^ ...because it uses `Self` as a type parameter
45  |     + Product
    |       ^^^^^^^ ...because it uses `Self` as a type parameter
    |
   ::: /Users/~~/.cargo/registry/src/github.com-1ecc6299db9ec823/num-traits-0.2.14/src/lib.rs:67:41
    |
67  | pub trait Num: PartialEq + Zero + One + NumOps {
    |                ^^^^^^^^^                ^^^^^^ ...because it uses `Self` as a type parameter
    |                |
    |                ...because it uses `Self` as a type parameter
...
149 | pub trait NumAssign: Num + NumAssignOps {}
    |                            ^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
    |
   ::: /Users/~~/.cargo/registry/src/github.com-1ecc6299db9ec823/num-traits-0.2.14/src/identities.rs:12:25
    |
12  | pub trait Zero: Sized + Add<Self, Output = Self> {
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^
    |                         |         |
    |                         |         ...because it uses `Self` as a type parameter
    |                         ...because it uses `Self` as a type parameter
...
90  | pub trait One: Sized + Mul<Self, Output = Self> {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^
    |                        |         |
    |                        |         ...because it uses `Self` as a type parameter
    |                        ...because it uses `Self` as a type parameter

您的Type实际上不是数据类型,而是trait 当你为一个 trait 写一个impl时,你实际上是为那个 trait 的dyn object 版本写的,这通常不是你想要的。 事实上,您可能会收到如下警告:

warning: trait objects without an explicit `dyn` are deprecated

出现错误的 rest 是因为您的特征要求不是动态对象安全的。

您可能需要的是特征中的简单 function :

pub trait Type: Lapack + Scalar + Float + Sync + Send {
    fn abs(&self) -> Self;
}
impl Type for f32 {
    fn abs(&self) -> Self {
        Self::abs(*self)
    }
}
impl Type for f64 {
    fn abs(&self) -> Self {
        Self::abs(*self)
    }
}

是的,您必须为实现Type的每种类型重复代码,但对于这种情况,这几乎不会带来不便。

如果有很多类型和很多函数,您可以使用宏,这就是大多数库所做的。

暂无
暂无

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

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