[英]Implementing Index trait to return a value that is not a reference
I have a simple struct that I would like to implement Index
for, but as a newcomer to Rust I'm having a number of troubles with the borrow checker.我有一个简单的结构,我想为其实现
Index
,但是作为 Rust 的新手,我在借用检查器方面遇到了许多麻烦。 My struct is pretty simple, I'd like to have it store a start and step value, then when indexed by a usize
it should return start + idx * step
:我的结构非常简单,我想让它存储一个开始和步长值,然后当由
usize
索引时它应该返回start + idx * step
:
pub struct MyStruct {
pub start: f64,
pub step: f64,
}
My intuition is that I'd simply be able to take the signature of Index
and plug in my types:我的直觉是,我可以简单地获取
Index
的签名并插入我的类型:
impl Index<usize> for MyStruct {
type Output = f64;
fn index(&self, idx: usize) -> &f64 {
self.start + (idx as f64) * self.step
}
}
This gives the error mismatched types
saying expected type &f64, found type f64
.这给出了错误
mismatched types
表示expected type &f64, found type f64
。 As someone who has yet to fully understand how Rust's type system works, I tried simply slapping &
on the expression:作为尚未完全理解 Rust 的类型系统如何工作的人,我尝试简单地在表达式上加上
&
:
fn index(&self, idx: usize) -> &f64 {
&(self.start + (idx as f64) * self.step)
}
This now tells me that the borrowed value does not live long enough
, so maybe it needs a lifetime variable?这现在告诉我,
borrowed value does not live long enough
,所以也许它需要一个生命周期变量?
fn index<'a>(&self, idx: usize) -> &'a f64 {
&(self.start + (idx as f64) * self.step)
}
The error is the same, but the note now gives lifetime 'a
instead of lifetime #1
, so I guess that's not necessary, but at this point I feel like I'm stuck.错误是一样的,但注释现在给出了
lifetime 'a
而不是lifetime #1
,所以我想这没有必要,但在这一点上我觉得我被卡住了。 I'm confused that such a simple exercise for most languages has become so difficult to implement in Rust, since all I want to do is return a computation from a function that happens to be behind a reference.我很困惑,对于大多数语言来说,这样一个简单的练习在 Rust 中变得如此难以实现,因为我想要做的就是从恰好位于引用后面的函数返回一个计算。 How should I go about implementing
Index
for a simple structure where the value is calculated on demand?我应该如何为按需计算值的简单结构实施
Index
?
The Index
trait is meant to return a borrowed pointer to a member of self
(eg an item in a Vec
). Index
trait 旨在返回一个借用的指向self
成员的指针(例如Vec
一个项目)。 The signature of the index
method from the Index
trait makes it impractical to implement it to have the behavior you described, as you'd have to store every value returned by index
in self
and ensure that the pointers remain valid until the MyStruct
is dropped.来自
Index
trait 的index
方法的签名使得实现它以具有您描述的行为是不切实际的,因为您必须将index
返回的每个值存储在self
并确保指针在MyStruct
被删除之前保持有效。
This use case does not match the intuition for Index
.此用例与
Index
的直觉不匹配。 When I see myStruct[3]
, my intuition is that, just as for arrays, I'm getting a pointer to some already-initialized data.当我看到
myStruct[3]
,我的直觉是,就像数组一样,我得到了一个指向一些已初始化数据的指针。 The interface for Index
corroborates this intuition. Index
的界面证实了这一直觉。
I can see two things that you might potentially be trying to achieve:我可以看到您可能试图实现的两件事:
In this case I would recommend against the premise of implementing Index
and just provide a method that returns a f64
instead of an &f64
like so.在这种情况下,我建议反对实现
Index
的前提,只提供一种返回f64
而不是&f64
。
impl MyStruct {
pub fn index(&self, idx: usize) -> f64 {
self.start + (idx as f64) * self.step
}
}
You don't get the operators, which is good because somebody reading []
would be mislead into thinking they were getting a pointer.你没有得到操作符,这很好,因为有人阅读
[]
会被误导,认为他们得到了一个指针。 But you do get the functionality you want.但是你确实得到了你想要的功能。 Depending on your use cases you may want to rename this method.
根据您的用例,您可能希望重命名此方法。
MyStruct
to a parameter with Index
bounds.MyStruct
传递给具有Index
边界的参数。 This is trickier with good reason.这是有充分理由的棘手。
Index
expects the data to be there before it asks for it. Index
期望数据在它要求之前就在那里。 You can't generate and return it because index
returns f64
, and you can't generate it in the datastructure and return a pointer because it doesn't take a &mut self
.您无法生成并返回它,因为
index
返回f64
,并且您无法在数据结构中生成它并返回一个指针,因为它不接受&mut self
。 You'd have to populate these values before the call to index
.您必须在调用
index
之前填充这些值。 Some redesign would be in order, and the direction of that redesign would depend on the larger context of your problem.一些重新设计将是有序的,重新设计的方向将取决于您的问题的更大背景。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.