实现索引特征以返回不是引用的值

时间:2016-08-24 02:50:44

标签: indexing rust

我有一个简单的结构,我想实现Index,但作为Rust的新手,我在借用检查器方面遇到了许多麻烦。我的结构非常简单,我想让它存储起始值和步长值,然后当由usize索引时它应该返回start + idx * step

pub struct MyStruct {
    pub start: f64,
    pub step: f64,
}

我的直觉是,我能够采用Index的签名并插入我的类型:

impl Index<usize> for MyStruct {
    type Output = f64;

    fn index(&self, idx: usize) -> &f64 {
        self.start + (idx as f64) * self.step
    }
}

这会导致错误mismatched typesexpected type &f64, found type f64。作为尚未完全理解Rust类型系统如何工作的人,我尝试简单地在表达式上单击&

fn index(&self, idx: usize) -> &f64 {
    &(self.start + (idx as f64) * self.step)
}

这现在告诉我borrowed value does not live long enough,所以它可能需要一个生命周期变量?

fn index<'a>(&self, idx: usize) -> &'a f64 {
    &(self.start + (idx as f64) * self.step)
}

错误是相同的,但现在注释中提到的是lifetime 'a而不是lifetime #1,所以我猜这不是必要的,但此时此刻我感觉自己就像我一样卡住。我很困惑,大多数语言的这种简单练习在Rust中很难实现,因为我想做的就是从恰好位于引用后面的函数返回一个计算。我应该如何为一个简单的结构实现Index,其中值是按需计算的?

2 个答案:

答案 0 :(得分:3)

Index特征旨在将借用的指针返回给self的成员(例如Vec中的项目)。来自index特征的Index方法的签名使得实现它以实现您描述的行为是不切实际的,因为您必须将index返回的每个值存储在{self中。 1}}并确保指针在MyStruct被删除之前保持有效。

答案 1 :(得分:1)

此用例与Index的直觉不符。当我看到myStruct[3]时,我的直觉是,就像数组一样,我得到了一些已经初始化的数据的指针。 Index的界面证实了这种直觉。

我可以看到你可能想要实现的两件事:

  1. 为您的数据结构获取不错的索引语法。
  2. 在这种情况下,我建议不要实施Index的前提,只提供一个返回f64而不是&f64的方法。

    impl MyStruct {
        pub fn index(&self, idx: usize) -> f64 {
            self.start + (idx as f64) * self.step
        }
    }
    

    你没有得到操作员,这很好,因为有人读[]会误导他们认为他们得到了一个指针。但是你确实得到了你想要的功能。根据您的使用情况,您可能需要重命名此方法。

    1. MyStruct传递给Index边界的参数。
    2. 这很有道理。 Index期望数据在它要求之前存在。您无法生成并返回它,因为index会返回f64,并且您无法在数据结构中生成它并返回指针,因为它没有&mut self 1}}。您必须在调用index之前填充这些值。一些重新设计将是有序的,重新设计的方向将取决于您的问题的更大背景。