2016-08-24 43 views
3

我有一个简单的结构,我想实现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。正如有人谁尚未完全了解锈病的类型系统是如何工作的,我试着拍打只是在表达&

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以获得按需计算价值的简单结构?

回答

3

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

+0

那么在MyStruct上实现一个名为'index'或'at'的方法只需要一个'usize'并返回一个'f64'?我还想实现使用Python片段(我认为是生锈的''Range)进行索引的能力,使用'...'语法作为函数参数可能吗? – bheklilr

+0

您可以编写一个独立的'index'方法,但是您将无法将它与索引语法('x [i]')结合使用。范围语法产生具有由标准库提供的类型的值(例如'x..y'产生['Range'](https://doc.rust-lang.org/stable/std/ops/struct.Range.html )值)。 –

+0

所以基本上我只是在这里运气不好?哦,这不是什么大不了的事,只是一种学习新语言的不同范式。 – bheklilr

1

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

我可以看到两件事情,你可能会潜在地努力实现:

  1. 获得很好的索引语法的数据结构。

在这种情况下,我会建议不要实施Index的前提下,只是提供一个返回f64代替&f64像这样的方法。

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

你没有得到运营商来说,这是一件好事,因为有人读[]会被误导,以为他们得到的指针。但是你确实获得了你想要的功能。根据您的使用情况,您可能需要重命名此方法。

  1. MyStruct传递给带有Index范围的参数。

这很棘手,有很好的理由。 Index预计数据在它要求之前存在。您不能生成并返回它,因为index返回f64,并且不能在数据结构中生成它并返回一个指针,因为它不需要&mut self。在致电index之前,您必须填写这些值。一些重新设计将是有序的,重新设计的方向将取决于您的问题的更大范围。

+1

我想我现在看到,我的直觉不同于铁锈的惯例。但是,这些信息有点难以找到,因为生锈仍然是一种非常年轻的语言。我的方法基本上是你的第一个建议,尽管我用''at''这样一个特征去模拟'Index'的设计。如果存在“At ”的'impl',那么我已经想出了如何自动'在'范围''上,这对于Rust来说是非常方便的。 – bheklilr