我是Rust的新手,编写了一个二进制矩阵上的线性代数库.我有一个稀疏矩阵 struct ,它以列主格式(CscMatrix)存储一个矩阵.CscMatrix存储每列中1的位置,每列占据‘1’向量中的一个连续段.第i列的第一个条目的索引存储在开始[i]处.现在,我希望能够转置这样一个矩阵,并以行主格式接收结果(CsrMatrix的一个实例,它做的事情与CscMatrix完全相同,只是每一行占据‘one’中的一个连续段).当然,要做到这一点,不需要进行实际计算,只需将存储在CscMatrix中的数据重新解释为CsrMatrix即可.

pub struct CscMatrix {
    start: Vec<u32>, // start index of each column in 'ones'
    ones: Vec<u32>,  // positions of ones
}

pub struct CsrMatrix {
    start: Vec<u32>, // start index of each row in 'ones'
    ones: Vec<u32>,  // positions of ones
}

impl CscMatrix {
    pub fn transpose(&self) -> CsrMatrix {
        return CsrMatrix {
            start: self.start,
            ones: self.ones,
        };
    }
}

给定的CscMatrix始终是不可变的,并且返回的CsrMatrix不会被修改.

我现在的两个问题是:

  • 我是否可以使用与给定CscMatrix中完全相同的数据来初始化CsrMatrix的‘Start’和‘one’向量,而不必复制它?直观地说,这应该是可能的,因为我不想修改返回的CsrMatrix,并且给定的CscMatrix是不可变的.因此,只需复制"开始"和"一"指向的内存位置的指针即可.
  • 我可以让转置函数返回对创建的CsrMatrix对象的不可变引用吗?

推荐答案

某个对象,无论是原始的CscMatrix、获得的CsrMatrix,还是两者的合作,都需要拥有数据--需要有人负责保留包含数据的实际VEC,并在某个时候释放它.

您有几个选项:

  • CscMatrix和CsrMatrix可以保存Rc<Vec<u32>>个字段,其中Rc是提供不可变访问的引用计数容器.在这种情况下,在构造CsrMatrix时,您将clone个RC,但克隆RC只会增加引用计数,而不是实际复制整个向量.当RC的最后一个克隆被释放时,实际的向量也被释放,其内存也被释放.

    • 还有一个称为std::sync::Arc的线程安全变量.
    • RC本身不能安全地提供可变访问,因为可能有RC的其他克隆指向相同的数据.
  • CsrMatrix可以是CscMatrix上的轻量级视图,借鉴它:

    pub struct CsrMatrix<'a> {
        borrowed: &'a CscMatrix
    }
    

    这是非常严格的-CsrMatrix不能超过CscMatrix,CscMatrix在CsrMatrix活动期间不能移动,等等.这主要适用于CsrMatrix的短期临时使用.

  • 正如cdhowie's answer指出的那样,Cow提供了拥有或borrow 数据的灵活性.

我可以让转置函数返回对创建的CsrMatrix对象的不可变引用吗?

实际上并非如此--如果它在局部变量中创建一个CsrMatrix对象,那么它返回的引用将是一个悬空引用.如果您对类似引用的语义没有意见,那么您可能会想要使用上面的第二个选项.

Rust相关问答推荐

基于对vec值的引用从该值中删除该值

如何仅使用http机箱发送http请求?

定义采用更高级类型泛型的性状

除了调用`waker.wake()`之外,我如何才能确保future 将再次被轮询?

为昂贵的for循环制作筛子

如果死 struct 实现了/派生了一些特征,为什么Rust会停止检测它们?

如何返回 struct 体中向量的切片

有没有办法隐式绑定 let/match 操作的成员?

使用在功能标志后面导入的类型,即使未启用功能标志

不安全块不返回预期值

如何递归传递闭包作为参数?

如何限制通用 const 参数中允许的值?

LinkedList::drain_filter::drop 中 DropGuard 的作用是什么?

如何在 Rust 中编写修改 struct 的函数

TinyVec 如何与 Vec 大小相同?

如何将 u8 切片复制到 u32 切片中?

如何将 while 循环内的用户输入添加到 Rust 中的向量?

为什么我不能将元素写入 Rust 数组中移动的位置,但我可以在元组中完成

为什么在使用 self 时会消耗 struct 而在解构时不会?

有没有比多个 push_str() 调用更好的方法将字符串链接在一起?