为什么在两次使用之间对const变量的更改不持久? [英] Why do changes to a const variable not persist between usages?

查看:80
本文介绍了为什么在两次使用之间对const变量的更改不持久?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个结构来操纵文件存储,但是更改值后将无法使用它.我确定这是一辈子的事,但我不知道该如何解决.

I am trying to create a struct to manipulate file storage, but after I change the value it can not be used. I'm sure it's about lifetimes, but I do not understand how I can fix this.

use std::error::Error;
use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader};
use std::option::Option;
use std::path::Path;

pub struct Storage<'a> {
    path_str: &'a str,
    file: Option<File>,
}

const LOCKED_STORAGE: Storage<'static> = Storage {
    path_str: &"/tmp/bmoneytmp.bms",
    file: None,
};

pub fn get_instance() -> Storage<'static> {
    if LOCKED_STORAGE.file.is_none() {
        LOCKED_STORAGE.init();
    }

    LOCKED_STORAGE
}

impl Storage<'static> {
    // Create a file for store all data, if does not alred exists
    fn init(&mut self) {
        let path = Path::new(self.path_str);

        self.file = match OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .open(path)
        {
            Err(e) => panic!("Couldn't create the storage file at {}", e.description()),
            Ok(file) => Some(file),
        };

        if self.file.is_none() {
            panic!("Error on init??"); // This line is not called. Ok :)
        }
    }

    // Check if section exists
    pub fn check_section(&self, name: String) -> bool {
        if self.file.is_none() {
            panic!("Error on check??"); // This line is called. :(
        }
        true
    }
}

fn main() {
    let storage = get_instance();
    storage.check_section("accounts".to_string());
}

操场

此操作失败:

thread 'main' panicked at 'Error on check??', src/main.rs:48:13

我正在尝试使用一种方法来打开文件并读取此打开的文件,但是在第二种方法中,文件的实例未打开.使用Option<File>,用Same/None更改值,但变量仍为None.

I am trying to use a method to open a file and read this opened file, but in second method the instance of the file is not opened. Using Option<File>, I change the value with Same/None but the variable continues to be None.

推荐答案

感谢@shepmaster.您的回答使我学到了很多东西.但是我改变了方法,并使用Mutex全局static和lazy_static解决了问题.

Thanks @shepmaster. I am learned much with your answer. But i changed my approach and fix my problem using Mutex global static and lazy_static.

我还阅读了文章 https://bryce.fisher-fleig.org/blog/strategies-for-returning-references-in-rust/index.html ,它有助于我理解自己的错误.

Also i read the article https://bryce.fisher-fleig.org/blog/strategies-for-returning-references-in-rust/index.html and it helped me to understand my error.

我的新代码:

#[macro_use]
extern crate lazy_static;

use std::error::Error;
use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::option::Option;
use std::sync::Mutex;

pub struct Storage {
    path_str: String,
    file: Option<File>
}

lazy_static! {
    pub static ref LOCKED_STORAGE: Mutex<Storage> = Mutex::new(start_storage());
}

fn start_storage() -> Storage {
    let mut st = Storage { path_str: "/tmp/bmoneytmp.bms".to_string(), file: None };
    st.init();
    st
}

impl Storage {

    // Create a file for store all data, if does not alred exists
    fn init(&mut self) {

        let path = Path::new(&self.path_str);

        self.file = match OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .open(path)
        {
            Err(e) => panic!("Couldn't create the storage file at {}", e.description()),
            Ok(file) => Some(file),
        };
    }

    // Check if section exists
    pub fn check_section(&self, name: String) -> bool {

        let file = match &self.file {
            Some(file) => file,
            None => panic!("File of storage not opened")
        };

        for line in BufReader::new(file).lines() {
            println!("{}{:?}", name, line); // Working!!
        }

        true
    }
}

fn main() {
    // run in your bash before: echo "Row 1" >> /tmp/bmoneytmp.bms
    LOCKED_STORAGE.lock().unwrap().check_section("accounts".to_string());
}

您可以在操场上构建它: https://play.rust-lang.org/?gist=bbd47a13910e0f7cda908dc82ba290eb&version=beta&mode=debug&edition=2018

You can build this on playground: https://play.rust-lang.org/?gist=bbd47a13910e0f7cda908dc82ba290eb&version=beta&mode=debug&edition=2018

我的项目的完整代码: https://github.com/fernandobatels/blitz-money

Full code of my project: https://github.com/fernandobatels/blitz-money

我的修复程序的完整代码: https://github.com/fernandobatels/blitz-money/blob/9dc04742a57e6cd99742f2400a6245f210521f5d/src/backend/storage.rs

Full code of my fix: https://github.com/fernandobatels/blitz-money/blob/9dc04742a57e6cd99742f2400a6245f210521f5d/src/backend/storage.rs https://github.com/fernandobatels/blitz-money/blob/9dc04742a57e6cd99742f2400a6245f210521f5d/src/backend/accounts.rs

这篇关于为什么在两次使用之间对const变量的更改不持久?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆