[英]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.