如何在不消耗值的情况下实现Add trait
How to implement Add trait without consuming the value
当为简单结构实现 Add
特征(以及其他一些特征,如 Mul
、Sub
等)时,必须完全使用结构值,因此以后无法使用它。
同时,内置基元(u8
、usize
等)实现了 Add
,同时允许在调用 add
后使用它。
如何为我的结构实现 Add
以便在调用 add
后能够使用它?
use std::ops::Add;
struct I(usize);
impl Add for I {
type Output = Self;
fn add(self, rhs: Self) -> Self {
I(self.0 + rhs.0)
}
}
fn main() {
let a = 123;
let b = a + a; // no error
let a1 = I(123);
let b1 = a1 + a1;
println!("b={}", b);
}
error[E0382]: use of moved value: `a1`
--> src/main.rs:16:19
|
15 | let a1 = I(123);
| -- move occurs because `a1` has type `I`, which does not implement the `Copy` trait
16 | let b1 = a1 + a1;
| -- ^^ value used here after move
| |
| value moved here
您应该能够将 #[derive(Copy, Clone)]
添加到结构中,然后它不会使用该值,而是使用一个副本。
您可以 impl Deref
并取消引用该值。这将适用于 Add
类型的简单包装类型。
use std::ops::{Add, Deref};
struct I(usize);
impl Add for I {
type Output = Self;
fn add(self, rhs: Self) -> Self {
I(self.0 + rhs.0)
}
}
impl Deref for I {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let a = 123;
let b = a + a; // no error
let a1 = I(123);
// Note the dereferences.
let b1 = *a1 + *a1;
println!("b={}", b);
}
注意:在这种情况下,Ryan 的回答应该足够了,因为 usize
是克隆类型。
当为简单结构实现 Add
特征(以及其他一些特征,如 Mul
、Sub
等)时,必须完全使用结构值,因此以后无法使用它。
同时,内置基元(u8
、usize
等)实现了 Add
,同时允许在调用 add
后使用它。
如何为我的结构实现 Add
以便在调用 add
后能够使用它?
use std::ops::Add;
struct I(usize);
impl Add for I {
type Output = Self;
fn add(self, rhs: Self) -> Self {
I(self.0 + rhs.0)
}
}
fn main() {
let a = 123;
let b = a + a; // no error
let a1 = I(123);
let b1 = a1 + a1;
println!("b={}", b);
}
error[E0382]: use of moved value: `a1`
--> src/main.rs:16:19
|
15 | let a1 = I(123);
| -- move occurs because `a1` has type `I`, which does not implement the `Copy` trait
16 | let b1 = a1 + a1;
| -- ^^ value used here after move
| |
| value moved here
您应该能够将 #[derive(Copy, Clone)]
添加到结构中,然后它不会使用该值,而是使用一个副本。
您可以 impl Deref
并取消引用该值。这将适用于 Add
类型的简单包装类型。
use std::ops::{Add, Deref};
struct I(usize);
impl Add for I {
type Output = Self;
fn add(self, rhs: Self) -> Self {
I(self.0 + rhs.0)
}
}
impl Deref for I {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let a = 123;
let b = a + a; // no error
let a1 = I(123);
// Note the dereferences.
let b1 = *a1 + *a1;
println!("b={}", b);
}
注意:在这种情况下,Ryan 的回答应该足够了,因为 usize
是克隆类型。