Return 对象条目的可变实例
Return mutable instance of entry of an object
我想了解是否允许在 Rust 中获取对结构内部向量条目的可变引用。
我在结构中有一个向量,我想return对其索引字段之一的引用。
示例代码:
#[derive(Debug)]
pub struct Definition {
v1: Vec<(String, i32)>,
}
impl Definition {
fn new() -> Self {
Self {
v1: Vec::new(),
}
}
fn insert_some_values(&mut self) {
self.v1.push(("V1".to_string(), 0));
self.v1.push(("V2".to_string(), 1));
self.v1.push(("V3".to_string(), 2));
self.v1.push(("V4".to_string(), 3));
}
fn search(&mut self, st: String) -> Result<&mut (String, i32), u32> {
for i in &self.v1 {
if st.eq(&i.0) {
return Ok(I); // Is this supported in someway?
}
}
return Err(0);
}
}
fn main() {
let mut def = Definition::new();
def.insert_some_values();
let res = def.search("V2".to_string());
println!("{:?}", res);
}
很明显,只在编译时出错:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:23:27
|
23 | return Ok(i);
| ^ types differ in mutability
|
= note: expected mutable reference `&mut (String, i32)`
found reference `&(String, i32)`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
但是我想知道有没有什么办法可以支持?
很可能,它不受支持,因为通过这种方式,它实质上是将字段的部分所有权丢失给调用者,这是不允许的。也许只允许对结构中的各个项目拥有部分所有权,但不允许在对象内拥有。
但是如果支持的话,有人可以帮忙吗?
谢谢!
您尝试做的很好 — 您只是错过了一点:
fn search(&mut self, st: String) -> Result<&mut (String, i32), u32> {
for i in &mut self.v1 { // HERE
if st.eq(&i.0) {
return Ok(i);
}
}
return Err(0);
}
循环必须写成for i in &mut self.v1
(或者,等效地,for i in self.v1.iter_mut()
,这样你迭代的i
s是&mut
引用,而不是&
引用。通过此更改,您的代码将编译并 运行.
一些补充建议:
- 不要使用不必要的
return
s。
- 使用
==
代替 .eq()
。
- 不要 return 不传达任何信息的错误值 — 而是使用
Option
。
- 使用
&str
而不是 String
,这样调用者就没有义务传递随后将被释放的字符串。
fn search(&mut self, st: &str) -> Option<&mut (String, i32)> {
for i in self.v1.iter_mut() {
if i.0.as_str() == st {
return Some(i);
}
}
None
}
如果愿意,您也可以单独使用迭代器方法编写函数。这与循环相同,但可能更方便 and/or 可读 - 在这种情况下不一定,但在稍微复杂的情况下:
fn search(&mut self, st: &str) -> Option<&mut (String, i32)> {
self.v1.iter_mut().filter(|i| i.0.as_str() == st).next()
}
我想了解是否允许在 Rust 中获取对结构内部向量条目的可变引用。
我在结构中有一个向量,我想return对其索引字段之一的引用。
示例代码:
#[derive(Debug)]
pub struct Definition {
v1: Vec<(String, i32)>,
}
impl Definition {
fn new() -> Self {
Self {
v1: Vec::new(),
}
}
fn insert_some_values(&mut self) {
self.v1.push(("V1".to_string(), 0));
self.v1.push(("V2".to_string(), 1));
self.v1.push(("V3".to_string(), 2));
self.v1.push(("V4".to_string(), 3));
}
fn search(&mut self, st: String) -> Result<&mut (String, i32), u32> {
for i in &self.v1 {
if st.eq(&i.0) {
return Ok(I); // Is this supported in someway?
}
}
return Err(0);
}
}
fn main() {
let mut def = Definition::new();
def.insert_some_values();
let res = def.search("V2".to_string());
println!("{:?}", res);
}
很明显,只在编译时出错:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:23:27
|
23 | return Ok(i);
| ^ types differ in mutability
|
= note: expected mutable reference `&mut (String, i32)`
found reference `&(String, i32)`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
但是我想知道有没有什么办法可以支持?
很可能,它不受支持,因为通过这种方式,它实质上是将字段的部分所有权丢失给调用者,这是不允许的。也许只允许对结构中的各个项目拥有部分所有权,但不允许在对象内拥有。
但是如果支持的话,有人可以帮忙吗?
谢谢!
您尝试做的很好 — 您只是错过了一点:
fn search(&mut self, st: String) -> Result<&mut (String, i32), u32> {
for i in &mut self.v1 { // HERE
if st.eq(&i.0) {
return Ok(i);
}
}
return Err(0);
}
循环必须写成for i in &mut self.v1
(或者,等效地,for i in self.v1.iter_mut()
,这样你迭代的i
s是&mut
引用,而不是&
引用。通过此更改,您的代码将编译并 运行.
一些补充建议:
- 不要使用不必要的
return
s。 - 使用
==
代替.eq()
。 - 不要 return 不传达任何信息的错误值 — 而是使用
Option
。 - 使用
&str
而不是String
,这样调用者就没有义务传递随后将被释放的字符串。
fn search(&mut self, st: &str) -> Option<&mut (String, i32)> {
for i in self.v1.iter_mut() {
if i.0.as_str() == st {
return Some(i);
}
}
None
}
如果愿意,您也可以单独使用迭代器方法编写函数。这与循环相同,但可能更方便 and/or 可读 - 在这种情况下不一定,但在稍微复杂的情况下:
fn search(&mut self, st: &str) -> Option<&mut (String, i32)> {
self.v1.iter_mut().filter(|i| i.0.as_str() == st).next()
}