我们正在尝试在结构中保存一个句子,并且需要事先对其进行初始化,否则在match语句中不会知道结构(请参阅let data = ...
下面的代码)。
当我们调用该函数两次时(如fn main
部分所示),它会使用默认的初始化结构覆盖先前保存的句子并返回该函数。
是否有某种方法可以在#34; RET"的匹配声明中保存并保存该句子。不使用不安全的全局变量?
#[derive(Default)]
struct Test {
satz: String,
}
impl Test {
pub fn testing(message: &str) -> Result<Option<String>, &'static str> {
let mut vs: Vec<&str> = message.split(' ').collect();
let mut i = 0;
while vs[i] != "\n" {
i += 1;
if i > vs.len() {
Err("wrong format.").unwrap()
}
}
vs.truncate(i);
let data: Test = Default::default();
match vs[0] {
"PUB" => {
let data = Test { satz: vs.join(" ") };
Ok(None)
}
"RET" => {
let x = data.satz;
Ok(Some(x))
}
_ => Err("wrong format.")
}
}
}
fn main() {
Test::testing("PUBLISH Hey this is a short message! \n");
let a = Test::testing("RETRIEVE \n").unwrap().unwrap();
println!("{:?}", a);
}
答案 0 :(得分:2)
之前保存的句子
您似乎对数据的存储方式和位置感到非常困惑。我强烈建议您重新阅读The Rust Programming Language。在这种特定情况下,您应该格外小心,重新阅读并包括methods。
简单地说,Test::testing
无法存储数据。访问每个实例数据的方法具有self
参数。 Test::testing
是关联函数,而不是方法。
向该函数添加&mut self
会使其成为一种方法,然后将data
的所有用途替换为self
:
#[derive(Default)]
struct Test {
satz: String,
}
impl Test {
pub fn testing(&mut self, message: &str) -> Result<Option<String>, &'static str> {
let mut vs: Vec<_> = message.split(' ').collect();
let mut i = 0;
while vs[i] != "\n" {
i += 1;
if i > vs.len() {
Err("wrong format.").unwrap()
}
}
vs.truncate(i);
match vs[0] {
"PUB" => {
self.satz = vs.join(" ");
Ok(None)
}
"RET" => {
Ok(Some(self.satz.clone()))
}
_ => Err("wrong format.")
}
}
}
fn main() {
let mut t = Test::default();
t.testing("PUB Hey this is a short message! \n").unwrap();
let a = t.testing("RET \n").unwrap().unwrap();
println!("{:?}", a);
}
请注意,编译器试图告诉您出错了:
warning: unused variable: `data`
看来你认为data
有一些特殊含义可以让它在函数调用中持续存在 - 没有这样的东西。在没有明确存储数据的地方的情况下保持跨函数,将成为全局变量,并且出于多种原因这些是不可取的。
此外,您不应忽略警告,例如
warning: unused result which must be used
如果某些内容无法解决,请致电expect
(如果必须,请unwrap
)。
FWIW,我把它写成
impl Test {
pub fn testing(&mut self, message: &str) -> Result<Option<String>, &'static str> {
let message = message.trim();
let mut parts = message.splitn(2, " ");
match parts.next() {
Some("PUB") => {
let msg = parts.next().ok_or("wrong format.")?;
self.satz = msg.to_owned();
Ok(None)
}
Some("RET") => {
Ok(Some(self.satz.clone()))
}
_ => Err("wrong format.")
}
}
}