如何从移动到结构中的 Vec 中检索项目?
How do I retrieve an item from a Vec that is moved into a structure?
我有一个包含结构向量的结构,例如
fn main() {
let x: Vec<Item> = Vec::new();
// assume x is filled with stuff
do_things_with(x);
}
struct Item {
value: String,
}
struct Context {
x: Vec<Item>,
}
impl Context {
fn get(&mut self, at: usize) -> Item {
self.x[at]
}
}
fn do_things_with(x: Vec<Item>) {
let mut ctx = Context{
x: x,
};
ctx.get(5);
}
我有一个 Vec 的东西,我将它传递给某个函数,该函数创建一个上下文并将传递的值存储在该结构中。然后我想查看这个 Vec 中的项目,所以我有一些辅助函数,例如'get' 这将获取指定索引处的项目。
这似乎一切都很好,在 C 或任何语言中它会很好,但是 Rust 抱怨:
'cannot move out of borrowed content'
对于函数 'get',我们尝试访问向量中的项目。
我做错了什么?
这里的问题是 Vec
拥有它包含的 Item
的所有权,但是 Context.get
试图直接 return Item
(并取得它的所有权)。
如果 Context.get
只是需要让调用者查看向量的内容,它应该 return 引用一个 Item 而不是一个 Item:
impl Context {
fn get(&mut self, at: usize) -> &Item {
&self.x[at]
}
}
在上面的例子中,Context.get
可以对 self
进行不可变引用,因为它没有改变任何东西。此外,如果您想允许 Context.get
的调用者修改引用的项目,您将 return &mut Item
而不是 &Item
:
impl Context {
fn get(&mut self, at: usize) -> &mut Item {
&mut self.x[at]
}
}
编辑:正如@apemanzilla 在评论中的帮助指出的那样,如果您想要 Context.get 到 return Item 的单独副本,您也可以让 Item 实现 Clone
特性at
:
#[derive(Clone)]
struct Item {
value: String,
}
impl Context {
fn get(&mut self, at: usize) -> Item {
self.x[at].clone()
}
虽然更改 returned 项目不会修改 self.x 中包含的项目;这可能是也可能不是您想要的。
我有一个包含结构向量的结构,例如
fn main() {
let x: Vec<Item> = Vec::new();
// assume x is filled with stuff
do_things_with(x);
}
struct Item {
value: String,
}
struct Context {
x: Vec<Item>,
}
impl Context {
fn get(&mut self, at: usize) -> Item {
self.x[at]
}
}
fn do_things_with(x: Vec<Item>) {
let mut ctx = Context{
x: x,
};
ctx.get(5);
}
我有一个 Vec 的东西,我将它传递给某个函数,该函数创建一个上下文并将传递的值存储在该结构中。然后我想查看这个 Vec 中的项目,所以我有一些辅助函数,例如'get' 这将获取指定索引处的项目。
这似乎一切都很好,在 C 或任何语言中它会很好,但是 Rust 抱怨:
'cannot move out of borrowed content'
对于函数 'get',我们尝试访问向量中的项目。
我做错了什么?
这里的问题是 Vec
拥有它包含的 Item
的所有权,但是 Context.get
试图直接 return Item
(并取得它的所有权)。
如果 Context.get
只是需要让调用者查看向量的内容,它应该 return 引用一个 Item 而不是一个 Item:
impl Context {
fn get(&mut self, at: usize) -> &Item {
&self.x[at]
}
}
在上面的例子中,Context.get
可以对 self
进行不可变引用,因为它没有改变任何东西。此外,如果您想允许 Context.get
的调用者修改引用的项目,您将 return &mut Item
而不是 &Item
:
impl Context {
fn get(&mut self, at: usize) -> &mut Item {
&mut self.x[at]
}
}
编辑:正如@apemanzilla 在评论中的帮助指出的那样,如果您想要 Context.get 到 return Item 的单独副本,您也可以让 Item 实现 Clone
特性at
:
#[derive(Clone)]
struct Item {
value: String,
}
impl Context {
fn get(&mut self, at: usize) -> Item {
self.x[at].clone()
}
虽然更改 returned 项目不会修改 self.x 中包含的项目;这可能是也可能不是您想要的。