记Rust 1.85.0 及 Rust 2024升级后的几个坑

时间:2025-02-22 19:33   作者:ChenReal    阅读:41

听说,前两天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的其他新特性呢!

 

评论
0/200