Rust中static变量初始化函数编写疑问:两种写法为何一有效一失效?
Rust中static变量的初始化函数编写问题
问题原因
Rust对static变量的初始化有严格要求:初始化表达式必须是编译期可计算的常量表达式。
- 第一种写法里,
Object { field: BTreeMap::new() }直接使用结构体字面量调用BTreeMap::new(),而标准库中的BTreeMap::new()是const fn,能在编译阶段执行,因此整个表达式符合static初始化的要求。 - 第二种写法中,你自定义的
Object::new()只是普通函数,并非const fn,无法在编译期完成计算,所以不能用来初始化static变量。
解决方案
方案1:将new函数改为const fn
只要new函数内部的操作都符合const函数的规则(比如调用的子函数也是const fn),就可以直接修改:
static mutex: std::sync::Mutex<Object> = std::sync::Mutex::new(Object::new()); struct Object { field: BTreeMap<String, String>, } impl Object { const fn new() -> Object { Object { field: BTreeMap::new() } } }
方案2:使用延迟初始化(适合复杂逻辑)
如果Object::new()包含无法用const fn实现的复杂逻辑,可以借助lazy_static或once_cell crate实现运行期延迟初始化,变量会在第一次被访问时完成初始化:
use lazy_static::lazy_static; use std::collections::BTreeMap; use std::sync::Mutex; lazy_static! { static ref MUTEX: Mutex<Object> = Mutex::new(Object::new()); } struct Object { field: BTreeMap<String, String>, } impl Object { fn new() -> Object { Object { field: BTreeMap::new() } } }
内容的提问来源于stack exchange,提问作者user2138149
相关产品推荐
相关产品推荐

