【问题标题】:Generic math without copying in rust没有在 rust 中复制的通用数学
【发布时间】:2017-02-22 23:24:48
【问题描述】:

我想编写一些通用数学函数,而不假设我的类型是可复制的。这似乎是不可能的,因为数学运算符使用这些值,而不是借用它们。所以需要复制对象,只是为了简单的数学。我也可以只移动它们,但这在借用的上下文中是不可能的,当我想改变一个结构时,这是我需要的。

这里有一些简单的例子,问题出在哪里:

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
}

当我只想用结构的不可复制对象(例如向量的长度)计算某些东西时,它不起作用,因为该值将被消耗,因此结构变得无效,或者借用检查器说“不能离开借用的上下文”。 在变异结构时,我将如何正确使用通用数学? 是否只能用于可复制类型(或显式克隆)?

【问题讨论】:

  • 我对这个问题并不完全确定,但我的第一个想法是 Cont 本身没有 Add 运算符 - 只有 NoCopy 对象 - 甚至认为 Cont 是什么您要添加到NoCopy?另一种选择可能是使 cont 可变并具有 cont = Cont(cont.0 + rel)?
  • 这只是一个例子。实际上,这种方式可能会有问题,因为我的结构中有很多字段,并且还想在借用的上下文中使用它

标签: generics math rust


【解决方案1】:

一种选择是在引用上实现Add

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 没有被复制,那么单行方法可能需要更改。

在使用它的时候你必须添加引用,这很遗憾,但它可以正常工作:

fn main() {
    let x = NoCopy(1);
    let mut cont = Cont(x);
    let rel = NoCopy(2);
    cont.0=&cont.0+&rel;
}

(Playground)

【讨论】:

    猜你喜欢
    • 2022-01-14
    • 2020-01-13
    • 2020-06-20
    • 2020-05-24
    • 2017-12-07
    • 2020-10-11
    • 2021-02-13
    • 1970-01-01
    • 2011-06-23
    相关资源
    最近更新 更多