Rust吐槽日記#1

大家好,我是練習兩年半的Rust實習生,R你太美。

今天想來吐槽一下,Rust中的Option<Box<…>>。

如果我寫 Rust,一定是寫 Unsafe Rust。 ----- R你太美

當Safe 教徒們用Option<Box<…>>寫鏈表時,他們的代碼:

注意,以下代碼由CloseAI贊助R你太美。

impl Solution {
    pub fn reverse_between(
        head: Option<Box<ListNode>>,
        left: i32,
        right: i32,
    ) -> Option<Box<ListNode>> {
        // 建立 dummy 節點,簡化邊界情況(例如反轉第一個節點)
        let mut dummy = Some(Box::new(ListNode {
            val: 0,
            next: head,
        }));

        // 1. 移動到 left 前一個節點
        let mut prev = dummy.as_mut();
        for _ in 0..left - 1 {
            prev = prev.unwrap().next.as_mut();
        }

        // 2. 反轉區間 [left, right]
        let mut curr = prev.as_mut().unwrap().next.take(); // 拿出第 left 個節點
        let mut tail = curr.as_mut(); // 用來反轉

        for _ in left..=right {
            let mut next = curr.as_mut().unwrap().next.take(); // 下一個節點
            curr.as_mut().unwrap().next = prev.as_mut().unwrap().next.take();
            prev.as_mut().unwrap().next = curr;
            curr = next;
        }

        // 3. 將 tail 的 next 接上 curr(也就是 right + 1 節點)
        tail.unwrap().next = curr;

        dummy.unwrap().next
    }
}
4 Likes

以下是一些像我一樣學不會Safe Rust的垃圾們,請Safe Rust教徒來打救一下,R門。

下面這是兩個小黑子,總有人要黑我們家iKun,呀不對,是Safe Rust。

https://zhuanlan.zhihu.com/p/650386967

https://www.reddit.com/r/rust/comments/12b7p2p/the_rust_programming_language_absolutely/?tl=zh-hans

4 Likes

第一个哥们后面又写了一篇反转文章

反正不管他怎么说,他还是用的Rust来写他的交易系统

4 Likes

感謝你的回覆!我看完了該篇文章,請問你是怎麼看待Safe Rust教的呢?

4 Likes

我不认为写Rust一定要写safe Rust,unsafe不是说真的unsafe,只是unsafe代码块打破了编译器对于几种内存安全的限制,是否真正安全取决于写他的人。所以只要实现没问题,unsafe也是内存安全的
ps:你举的这几个例子不太能论证unsafe的必要性。那个n皇后的文章更是离谱,里面槽点太多了

4 Likes

这几个例子确实非常准确地指出了一些 Rust 不擅长的地方呢

第一个例子应该是想说明,Rust 在实现具有复杂所有权模式的数据结构时会让代码变得比较复杂,举的是链表的例子。不过请允许我指出,这个不好看的链表实现仍然是存在问题的:它在没有给整个 List 单独实现 Drop trait,这会导致链表头在 drop 的时候逐个递归尝试 drop 链表的后续节点,如果 llvm 没有准确领悟到这是个尾递归的话,链表一长就有栈空间溢出的风险了。

一般遇到这种问题的时候,会使用已经实现好的数据结构,比如 std::collections::LinkedList 或者 petgraph 之类的,把内存管理的难题限制在某单个 crate 中;也可以使用 arena 之类的内存管理方案绕开所有权系统;还有一种就是使用其它算法,之前在写无向图三角形计数的时候,我就是先把所有边存到一个 Vec 里去重,然后用 rayon 并行处理 —— 直接在存有所有边的数组,而不是图上运行算法。

第二个例子阐述了 Rust 的可读性问题。其中代码让人疑惑的地方主要是奇怪的异步函数的签名。这个确实没啥好办法,因为 Rust 的异步编程现在本身也不是什么充分解决了的问题,很多方案和语法糖要么东一套西一套藏在各家的异步运行时里,要么只有开 nightly 才能用。似乎只能等它慢慢发展了。其他令人疑惑的地方我猜就是 Option/Result、变量默认不可变和链式调用之类的,我觉得这只是因为大多数人入门编程的时候学的是 C/C++ 这样的语言,所以头脑里没有相关的概念;要是以 Ocaml 之类的语言入门的话,也许学起来会轻松很多。

第三个感觉只是习惯了 C with class 的算法竞赛选手写 Rust 闹了情绪而已……等他开始做 Real World 的项目时,应该能提出更有价值的意见吧……

我最近写的 Rust 程序主要是并行/异构计算、网站后端和一些用来调试网络的小工具。我感觉在这些地方,Safe Rust 是完全够用好用的。相比框架很少的 c、标准库很弱的 golang、永远学不会的 cxx、带一坨依赖的 python 和做原型很强但是后面写着写着就变成一团的 perl,Rust 确实有种乖巧可爱的感觉……

1 Like

Rust这链表写法真的秀,学废了学废了:sweat_smile:

1 Like

<<RUST圣经>> R 们

此话题已在最后回复的 30 天后被自动关闭。不再允许新回复。