创建静态常量

时间:2016-02-10 19:56:29

标签: static rust

我正在尝试通过匹配env :: home_dir来创建静态或常量:

static home: String = match env::home_dir() {
    Some(ref p) => p.to_str().unwrap().to_owned(),
    None => "./".to_string(),
};

但是我遇到了编译错误:

src/main.rs:15:8: 15:13 error: internal compiler error: no enclosing scope found for scope: CodeExtent(346/Misc(20))
src/main.rs:15          Some(ref p) => p.to_str().unwrap().to_owned(),
                             ^~~~~
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'Box<Any>', ../src/libsyntax/diagnostic.rs:175

这是我的代码中的错误还是应该报告此错误?是否可以将home作为常量或静态值?

我需要多次使用它来为某些文件操作添加一些文件名,我希望将它们全部放在同一个文件夹中。

2 个答案:

答案 0 :(得分:4)

  

这是我的代码中的错误

你的代码有一些没有意义的东西,所以我猜这是一个错误。

  

我应该报告这个错误吗?

可能。编译器不应该崩溃,它应该很好地向用户报告错误。首先查看是否存在现有错误,并在有错误时对其进行评论。

  

是否可以将home作为常量或静态值?

不完全是。 整个程序长度需要常量值。这意味着它们会在main开始之前和main退出之后存在。 env::home_dir()的电话无法满足这一准确标准。

最直接的做法是获取一次值,然后将其传递到需要的地方。这样可以避免多次获取该值:

fn main() {
    let home = env::home_dir();
    let home = home.as_ref().map(|d| d.as_path()).unwrap_or(Path::new("./"));

    function_1(&home);
    function_2(&home);
    function_3(&home);
}

您也可以将其作为&PathPathBuf放入结构中:

struct Thing {
    home: PathBuf,
}

fn main() {
    let home = env::home_dir().unwrap_or_else(|| PathBuf::from("./"));
    let t = Thing { home: home };

    t.function_1();
    t.function_2();
    t.function_3();
}

这可能就是我要做的。没有理由将永久分配给内存,因为静态值会。

  

我需要多次使用它来为某些文件操作添加一些文件名,我希望将它们全部放在同一个文件夹中。

没有什么可以阻止你简单地创建一个函数来放置逻辑:

fn safe_home_dir() -> PathBuf {
    env::home_dir().unwrap_or_else(|| PathBuf::from("./"))
} 

然后只需多次调用该函数。你可以看看它有多贵,但我的直觉是这里不会有明显的缓慢。

如果确实需要它是静态的,那么您可以使用lazy_static crate

答案 1 :(得分:2)

答案

静态变量不能有逻辑,要做到这一点,你必须使用lazy_static包,这使你能够做逻辑。一个小笔记,为了访问可靠的你必须尊重它。因此println!("{}", HOME);不起作用,但println!("{}", *HOME);会起作用。

解决方案

#[macro_use]
extern crate lazy_static;
use std::env;
lazy_static! {
    static ref HOME: String = {
        match env::home_dir() {
            Some(p) => p.to_str().unwrap().to_owned(),
            None => "./".to_string(),
        }
    };
}

fn main() {
    println!("{:?}", *HOME);
}