我们如何在多个调用中保存和检索结构中的变量?

时间:2017-05-19 09:11:12

标签: rust

我们正在尝试在结构中保存一个句子,并且需要事先对其进行初始化,否则在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);
}

1 个答案:

答案 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.")
        }
    }
}