听说,前两天Rust发布了1.85.0 及 Rust 2024,趁周末有点空闲,升级体验了一把……
据说,1.85.0算是个里程碑式的版本,Rust 2024上阵。而且,还带来许多新的特性,比如包括了我最想要的异步闭包。详情请参考官方Blog:
https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html
说干就干!立马敲下升级命令:
rustup update stable
升级成功!
stable-x86_64-apple-darwin updated - rustc 1.85.0 (4d91de4e4 2025-02-17) (from rustc 1.82.0 (f6e511eec 2024-10-15))
然后,打开项目,体验一把!记得改一下Cargo.toml
,将edition
改为2024,才能完整体(踩)验(坑)哦~
[package]
name = "my_app"
version = "0.1.0"
edition = "2024"
cargo run
之后,不出意外地马上出意外了!
坑NO.1 : Blocking waiting for file lock on package cache
没法编译运行,出现了Blocking waiting for file lock on package cache
的提示。
解决方法很简单,删除之前的编译缓存即可。
具体就是 rm -rf ~/.cargo/.package-cache
,完了之后再 cargo run
。
坑NO.2:creating a shared reference to mutable static is discouraged
升级前能正常编译运行的代码,居然报错了!
error: creating a shared reference to mutable static is discouraged
--> webapi/src/services/m_article_service.rs:190:21
|
190 | for item in CATEGROY_MAPS.clone() {
| ^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
大概意思就是:static mut
这种声明全局静态变量的语法不安全,不再被Rust 2024支持了,请自觉更换一下吧!
好吧,咱们也与时俱进一下,升级一下代码实现方式。正好我也看它不顺眼!点开官方文档链接:https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html
里面给我们推荐好几个替代方案,我选择了OnceLock
。因为之前用过Once
,感觉名字相似,也许血缘相近,故此颇有好感。
原来的代码长得是这个样子的,看他不顺眼,主要是这个unsafe
!玩Rust的两大追求,便是性能和安全。这里突然来个“unsafe”,怎么看都觉得碍眼,不是吗?
static mut CATEGROY_MAPS: Vec<KeyValue> = vec![];
fn get_category_id_by_name(name:&str) -> i32 {
unsafe {
if CATEGROY_MAPS.len() == 0 {
let map_str: String = get_env_var_default("TITLE_MAP_CATEGORY","[]");
CATEGROY_MAPS = serde_json::from_str(&map_str).unwrap();
}
for item in CATEGROY_MAPS.clone() {
if name.contains(item.name.as_str()) {
return item.id
}
}
}
0
}
改成OnceLock的实现:
static CATEGROY_MAPS_STATE: OnceLock<Vec<KeyValue>> = OnceLock::new();
fn get_category_id_by_name(name:&str) -> i32 {
let list = CATEGROY_MAPS_STATE.get_or_init(|| {
let map_str: String = get_env_var_default("TITLE_MAP_CATEGORY","[]");
serde_json::from_str(&map_str).unwrap()
});
for item in list.clone() {
if name.contains(item.name.as_str()) {
return item.id
}
}
0
}
最后,再cargo run
,一切正常!
好了,坑填已经完,那么文章就告一段落了。
我还要继续去解锁Rust 2024的其他新特性呢!