将参数值分配给构造函数中的许多结构成员,类似于 Rust 函数
Assign a parameter value to many struct members in a contructor similar function Rust
我在使用泛型类型创建简单结构时遇到问题,如下所示:
struct Point3<T> {
pub x: T,
pub y: T,
pub z: T,
}
impl<T> Point3<T>
{
fn create3(vx: T, vy: T, vz: T) -> Point3<T> {
Point3::<T> {
x: vx,
y: vy,
z: vz,
}
}
fn create1(v: T) -> Point3<T> {
Point3::<T> {
x: v,
y: v,
z: v,
}
}
}
但是当我试图编译它时,我得到了一个错误:
fn create1(v: T) -> Point3<T> {
| - move occurs because `v` has type `T`, which does not implement the `Copy` trait
34 | Point3::<T> {
35 | x: v,
| - value moved here
36 | y: v,
| ^ value used here after move
据我所知,v
已移至 x
,因此不适用于 y
或 z
。
所以看来我需要复制它,但我不知道该怎么做,也不知道如何为 T
实现 Copy
特性,因为它是通用类型
如果我通过 ref v
我有另一个错误
我敢肯定它很简单,但作为一个 c/c++ dev rust 目前对我来说很复杂 :)
当使用类型参数时,Rust 对类型的唯一假设是它是 Sized
。必须明确写出对类型参数的任何其他约束。
此外,Rust 的默认移动语义意味着一个值只能有一个所有者,一旦一个值被“移出”一个地方,它就不再有效。您可以通过实现 Copy
来选择退出此行为,尽管这仅对可以有意义地 memcpy
-ed 的类型有效,所以很多东西不能使用它(任何带有 [=14= 的东西) ] 实现,&mut T
,等等)。 TLDR,穿上 API.
是一个相当严格的限制
更一般的情况是 Clone
,它是 Copy
的超特征(这意味着:任何实现 Copy
的 T
,也实现 Clone
).不同之处在于 Clone
可能是一个昂贵的操作,可能需要堆分配,并且必须通过 Clone::clone
显式调用,但权衡是它的适用范围更广。
所以我建议按如下方式重写您的代码:
// this function doesn't need to impose any special bounds on T,
// since it never needs to be cloned
impl<T> Point3<T> {
fn create3(x: T, y: T, z: T) -> Self {
Self { x, y, z }
}
}
// this function does require clone, so we have to add the bound
impl<T: Clone> Point3<T> {
fn create1(v: T) -> Self {
Self {
x: v.clone(),
y: v.clone(),
z: v,
}
}
}
这允许您的 API 被更多的类型使用,但也不会为 Copy
类型增加任何性能开销,因为 Clone
实现的类型也是Copy
基本上是一个标准memcpy
.
诚然,对于一个名为 Point3
的结构,它可能只会用于数字,因此 Copy
与 Clone
的区别不是很相关,但在一般情况下,Clone
边界的使用范围更广。
我在使用泛型类型创建简单结构时遇到问题,如下所示:
struct Point3<T> {
pub x: T,
pub y: T,
pub z: T,
}
impl<T> Point3<T>
{
fn create3(vx: T, vy: T, vz: T) -> Point3<T> {
Point3::<T> {
x: vx,
y: vy,
z: vz,
}
}
fn create1(v: T) -> Point3<T> {
Point3::<T> {
x: v,
y: v,
z: v,
}
}
}
但是当我试图编译它时,我得到了一个错误:
fn create1(v: T) -> Point3<T> {
| - move occurs because `v` has type `T`, which does not implement the `Copy` trait
34 | Point3::<T> {
35 | x: v,
| - value moved here
36 | y: v,
| ^ value used here after move
据我所知,v
已移至 x
,因此不适用于 y
或 z
。
所以看来我需要复制它,但我不知道该怎么做,也不知道如何为 T
实现 Copy
特性,因为它是通用类型
如果我通过 ref v
我有另一个错误
我敢肯定它很简单,但作为一个 c/c++ dev rust 目前对我来说很复杂 :)
当使用类型参数时,Rust 对类型的唯一假设是它是 Sized
。必须明确写出对类型参数的任何其他约束。
此外,Rust 的默认移动语义意味着一个值只能有一个所有者,一旦一个值被“移出”一个地方,它就不再有效。您可以通过实现 Copy
来选择退出此行为,尽管这仅对可以有意义地 memcpy
-ed 的类型有效,所以很多东西不能使用它(任何带有 [=14= 的东西) ] 实现,&mut T
,等等)。 TLDR,穿上 API.
更一般的情况是 Clone
,它是 Copy
的超特征(这意味着:任何实现 Copy
的 T
,也实现 Clone
).不同之处在于 Clone
可能是一个昂贵的操作,可能需要堆分配,并且必须通过 Clone::clone
显式调用,但权衡是它的适用范围更广。
所以我建议按如下方式重写您的代码:
// this function doesn't need to impose any special bounds on T,
// since it never needs to be cloned
impl<T> Point3<T> {
fn create3(x: T, y: T, z: T) -> Self {
Self { x, y, z }
}
}
// this function does require clone, so we have to add the bound
impl<T: Clone> Point3<T> {
fn create1(v: T) -> Self {
Self {
x: v.clone(),
y: v.clone(),
z: v,
}
}
}
这允许您的 API 被更多的类型使用,但也不会为 Copy
类型增加任何性能开销,因为 Clone
实现的类型也是Copy
基本上是一个标准memcpy
.
诚然,对于一个名为 Point3
的结构,它可能只会用于数字,因此 Copy
与 Clone
的区别不是很相关,但在一般情况下,Clone
边界的使用范围更广。