gpt4 book ai didi

rust - 如何在Abs中实现Abs函数以自定义类型?

转载 作者:行者123 更新时间:2023-12-03 11:36:13 65 4
gpt4 key购买 nike

我目前正在使用Rust编写数字代码。所以我自己为它创建了一个类型。
此特征是允许rust_ndarray在f64和f32上执行计算的数据方式。为了使其具有多线程,我们在特征的边界添加了“同步”和“发送”。
如何在其他整数类型中找到的我自己的类型中实现函数?

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 {}
我想编写自己的函数来查找此Type的绝对值。
我该如何实现?
我做了如下所示的实现,并收到以下错误。
impl Type {
pub fn abs(&self) -> Self {
if self.0 > 0. {self.0}
else {-1. * self.0}
}
}
我收到以下错误。
鉴于我收到的错误,我在Type中使用的特征边界似乎有问题。我还尝试在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实际上不是数据类型,而是特征。而且,当您为特征编写impl时,实际上是为该特征的dyn对象版本编写的,而这通常不是您想要的。实际上,您可能会收到类似以下的警告:

warning: trait objects without an explicit `dyn` are deprecated
由于您的特征要求不是动态对象安全的,因此会出现其余错误。
您可能需要的是特征中的一个简单函数:
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的每种类型重复该代码,但是在这种情况下,这几乎没有什么不便之处。
如果有很多类型和很多功能,则可以使用宏,这就是大多数库所做的。

关于rust - 如何在Abs中实现Abs函数以自定义类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66114738/

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