问题描述
我想编写一些通用的数学函数,而不假定我的类型是可复制的.这似乎是不可能的,因为数学运算符使用这些值而不是借用它们.因此,仅出于简单的数学目的,就需要复制对象.我也可以移动它们,但是在我想要对结构进行突变时,在借用的上下文中是不可能的.
I want to write some generic math functions, without assuming that my types are copyable. This seems not to be possible, since math operators consume the values, instead of borrowing them. So it is required to copy the object, just for simple math. I could also just move them, but this is not possible in borrowed context, which I need, when I want to mutate a struct.
下面是一个简单的示例,其中有问题:
Here some simple example, where are problems:
use std::ops::Add;
struct NoCopy<T>(T); //some non-copyable struct, (maybe a vector)
struct Cont<T>(NoCopy<T>); //some struct contaioning a noncopyable struct
impl<T: Add<Output=T>> Add for NoCopy<T> {
type Output = NoCopy<T>;
fn add(self, x: NoCopy<T>) -> NoCopy<T> {
NoCopy(self.0+x.0)
}
}
fn main() {
let x = NoCopy(1);
let cont = Cont(x);
let rel = NoCopy(2);
cont.0=cont.0+rel; //addition makes struct cont invalid, so i have to copy
}
当我只想使用结构的不可复制对象(例如,向量的长度)来计算某些东西时,它将无法工作,因为该值将被消耗,因此该结构将变得无效,或者借用检查器说不能移出借用上下文".变异结构时,如何正确使用通用数学?只能复制类型(或显式克隆)吗?
And when I just want to calculate something with a not copyable object of a struct (for example the length of a vector), it won't work, since the value will either be consumed, so the struct gets invalid, or the borrow checker says "cannot move out of borrowed context".How would I correctly use a generic math, when mutating structs?Is it only possible for copyable types (or explicit cloning)?
推荐答案
一种选择是在引用上实现Add
:
One option is to implement Add
on references:
impl<'a, T: Copy + Add<Output = T>> Add for &'a NoCopy<T> {
type Output = NoCopy<T>;
fn add(self, rhs: Self) -> NoCopy<T> {
NoCopy(self.0+rhs.0)
}
}
这是可以的,因为共享引用是Copy
.注意,我在T
中添加了Copy
约束,以使此实现变得简单(对于整数,则为true);如果未复制T
,则可能需要更改单线方法.
This is ok since shared references are Copy
. Note I added a Copy
constraint to T
to make this implementation simple (true for integers); if T
isn't copy then the one-liner method might need to change.
使用时确实必须添加引用,这很可惜,但是它可以正常工作:
You do have to add references when using it, which is a shame, but it otherwise works:
fn main() {
let x = NoCopy(1);
let mut cont = Cont(x);
let rel = NoCopy(2);
cont.0=&cont.0+&rel;
}
(游乐场)
这篇关于通用数学,不会复制生锈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!