[英]Assign a parameter value to many struct members in a contructor similar function Rust
I have an issue with a simple struct creation with generic type, as follows:我在使用泛型类型创建简单结构时遇到问题,如下所示:
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,
}
}
}
but when I tried to compile it, I got an error:但是当我尝试编译它时,我得到了一个错误:
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
I understand than v
is moved in x
and so not available for y
or z
.我了解
v
在x
中移动,因此不适用于y
或z
。 so it seems I need to copy it, but I don't know how to do that, nor implement the Copy
trait for T
since its a generic type所以看来我需要复制它,但我不知道该怎么做,也不知道
T
的Copy
特性,因为它是通用类型
If I pass v
by ref I have another error如果我通过 ref 传递
v
我有另一个错误
I'm sure it's pretty simple, but as ac/c++ dev rust is complex to me for the moment:)我敢肯定它很简单,但是 ac/c++ dev rust 目前对我来说很复杂:)
When working with type parameters, the only thing that Rust assumes about the type is that it is Sized
.使用类型参数时,Rust 唯一假设的类型是它是
Sized
。 Any other constraints on the type parameter must be explicitly written out.必须明确写出对类型参数的任何其他约束。
Also, Rust's default move semantics mean that a value can have only a single owner, and that once a value is "moved out of" a place, it is no longer valid there.此外,Rust 的默认移动语义意味着一个值只能有一个所有者,并且一旦一个值被“移出”一个地方,它就不再有效。 You can opt out of this behaviour by implementing
Copy
, though this is only valid for types that can be meaningfully memcpy
-ed, so many things can't use this (anything with a Drop
impl, &mut T
, and more).您可以通过实现
Copy
来选择退出此行为,尽管这仅对可以有意义地memcpy
-ed 的类型有效,因此很多东西不能使用它(任何带有Drop
impl、 &mut T
等的东西)。 TLDR, it's a fairly restrictive bound to put on an API. TLDR,穿上 API 是一个相当严格的限制。
The much more general case is Clone
, which is a supertrait of Copy
(which means: any T
that implements Copy
, also implements Clone
).更一般的情况是
Clone
,它是Copy
的超特征(这意味着:任何实现Copy
的T
也实现Clone
)。 The difference is that Clone
is potentially an expensive operation, potentially requiring heap allocations, and must be explicitly called via Clone::clone
, but the tradeoff is that it is far more widely applicable.不同之处在于
Clone
可能是一项昂贵的操作,可能需要堆分配,并且必须通过Clone::clone
显式调用,但代价是它的适用范围要广得多。
So I'd suggest rewriting your code as follows:所以我建议按如下方式重写您的代码:
// 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,
}
}
}
This allows your API to be used by significantly more types, but also doesn't add any performance overhead for Copy
types, since the Clone
implementation for a type that is also Copy
is basically a standard memcpy
.这允许您的 API 被更多的类型使用,但也不会为
Copy
类型增加任何性能开销,因为同样是Copy
的类型的Clone
实现基本上是标准的memcpy
。
Admittedly, with a struct called Point3
, it's probably only going to be used for numbers, so the Copy
vs Clone
distinction isn't very relevant, but in the general case, a Clone
bound is more widely usable.诚然,对于名为
Point3
的结构,它可能只会用于数字,因此Copy
与Clone
的区别不是很相关,但在一般情况下, Clone
边界的使用范围更广。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.