У меня есть код, подобный:Как получить доступ к полям, связанным с переменной в выражении соответствия?
use std::string::{String};
use std::vec::{Vec};
enum State {
A {
n: usize,
lines: Vec<String>,
},
B {
n: usize,
}
}
fn main() {
use State::*;
let lines = vec!["a", "b", "GO", "c", "GO", "d"];
let mut state = B { n: 0 };
for line in &lines {
state = match state {
A { n, lines } => {
if line == &"GO" {
B { n: n + 1 }
} else {
let mut new_lines = Vec::from(lines);
new_lines.push(line.to_string());
A { n: n, lines: new_lines }
}
},
B { n } => {
A { n: n, lines: vec![line.to_string()] }
},
};
}
let final_n = match state {
A { n, .. } => n,
B { n } => n,
};
println!("final_n = {}", final_n);
}
Rust Playground ссылке: (. Заметим, что это упрощение реального кода См first revision этого вопроса для полного фона.) http://is.gd/0QTYaQ
Я хочу, чтобы не создавать вектор new_lines
, поэтому я попытался привязать значение State::A
к переменной и получить доступ к полям значения так:
s @ A { .. } => {
if line == &"GO" {
B { n: s.n + 1 }
} else {
s.lines.push(line.to_string());
s
}
},
Однако это не удается скомпилировать:
ParseState_enum_test.rs:23:28: 23:31 error: attempted access of field `n` on type `State`, but no field with that name was found ParseState_enum_test.rs:23 B { n: s.n + 1 } ^~~ ParseState_enum_test.rs:19:5: 33:6 note: in this expansion of for loop expansion ParseState_enum_test.rs:25:21: 25:28 error: attempted access of field `lines` on type `State`, but no field with that name was found ParseState_enum_test.rs:25 s.lines.push(line.to_string()); ^~~~~~~ ParseState_enum_test.rs:19:5: 33:6 note: in this expansion of for loop expansion error: aborting due to 2 previous errors
Как получить доступ к полям значения, связанного с переменной?
EDIT: Я знаю ref mut
в привязке к шаблону, но я не думаю, что это хорошее решение в моем случае. Если я использую ref mut
, то мне нужно, чтобы создать клон вектора, потому что этот код не компилируется:
A { n, ref mut lines } => {
if line == &"GO" {
B { n: n + 1 }
} else {
lines.push(line.to_string());
A {
n: n,
lines: lines, // error: mismatched types
}
}
},
I ** гарантия ** Вы можете [сделать меньший пример] (HTTP: // есть.gd/363IR1) :-) Это называется [MCVE] (/ help/mcve) и является очень хорошей идеей при задании вопроса о переполнении стека! Также обратите внимание, что наличие кода, который работает на [Rust Playground] (https://play.rust-lang.org/), является ** сильно ** предпочтительным. – Shepmaster
Это все еще очень долго по сравнению с вопросом, который вы задаете. – Shepmaster