如何声明一个静态向量数组?

4

如何在Rust中声明一个静态/常量数组,数组内嵌套变长数组(向量)?在C++中,你可以这样做:

static const std::vector<std::string> MY_STRINGS[] = {
    { "hi" },
    { "hello", "world" },
    { "salutations", "watery", "globe" }
};

如果您期望事情按照您的预期运行(我想在应用程序启动时构建数组),那么使用哪些Rust代码等效?似乎编译器正在全力阻止我这样做。


你需要包含一些 Rust 代码,展示你尝试过的内容以及你遇到的错误。你打算如何使用它?这将影响到如何实现它。 - Herohtar
它们可以是固定大小的数组,还是您计划在运行时添加/删除字符串? - John Kugelman
所有东西的大小和内容在编译时都是已知的 :) - elskrrrrt
3个回答

4

请注意,std::lazy::Lazy 不是线程安全的(相当于 once_cell::unsync::Lazy)。有 std::lazy::SyncLazy 可以进行线程安全访问。 - Chayim Friedman
@ChayimFriedman,是的,你在澄清方面提出了很好的观点。请随意编辑答案并添加该点。谢谢! - Netwave
但是,不允许将收集到数组中,仍然需要一个长文字代码... - Jiang YD
@JiangYD,肯定是允许的。也许你缺少了一些类型签名。 - Netwave
@Netwave let v:[Vec<u32>;2] = [1u32,2u32].iter().map(|x|vec![v]).collect(); 这样写可以吗? - Jiang YD
1
@JiangYD,你需要收集到一个Vec中,然后在懒加载的内容中进行try_into + unwrap,如果是const,就可以这样做。 - Netwave

1
如果你使用的是 nightly 版本,你可以使用 LazyLock。像这样:
#![feature(once_cell)]   // 1.65.0-nightly

use std::sync::LazyLock;

const MY_STRINGS: LazyLock<[Vec<&str>; 3]> =
    LazyLock::new(|| [
        vec!["hi"], 
        vec!["hello", "world"],
        vec!["salutations", "watery", "globe"]
    ]);

fn main() {
    println!("{}, {}", MY_STRINGS[1][0], MY_STRINGS[2][2]);
}

LazyLock或多或少地做了像crate once_celllazy_sync所做的事情。这两个crate非常常见,因此很有可能它们已经在您的Cargo.lock依赖树中。但是,如果您更喜欢稍微“冒险”一点,并选择LazyLock,请准备好它(就像nightly中的所有内容一样)在进入stable之前可能会发生变化。
(注:直到最近,std::sync::LazyLock的名称曾为std::lazy::SyncLazy,但最近已被重命名。)

0

目前你无法在带有析构函数的 'const' 项目中使用,因此不允许使用 Vec

如果你在编译时知道 "vec" 的大小,可以使用数组:

const MY_STRS: [&'static str; 3] = [
  "first",
  "second",
  "third"
];

否则,我建议看一下lazy_static包:https://crates.io/crates/lazy_static 这样你就可以写出像下面这样的代码:
lazy_static! {
  static ref MY_STRS: Vec<String> = {
    let mut strings = vec![];
    strings.push("hello".to_string());
    strings
  }
}

这个按照其名字的意思运作;即在首次访问时进行惰性初始化。

我建议阅读此板条箱的文档,以了解线程安全性方面的含义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接