monkeyWie
0.65D
V2EX  ›  Rust

最近初学 rust 有个疑问

  •  1
     
  •   monkeyWie · Dec 7, 2023 · 6342 views
    This topic created in 1062 days ago, the information mentioned may be changed or developed.

    rust 有空安全机制为什么不搞一套和 kotlin 和 dart 那样的空安全语法糖来替代手写 Option ,感觉写起来挺啰嗦的。

    对比下:

    • kotlin
    // 声明可空
    var number: Int? = null
    // 取值,为空时给默认值
    number ?: 0
    
    • dart
    // 声明可空
    int? number = null;
    // 取值,为空时给默认值
    number ?? 0
    
    • rust
    // 声明可空
    let number:Option<i32> = None;
    // 取值,为空时给默认值
    number.unwrap_or(0);
    

    可以看到 kotlin 和 dart 有语法糖写起来舒服多了,rust 为啥不支持下,写成这样:

    let number:i32? = None;
    number ?? 0
    

    当然还有更方便的链式调用,order?.user?.name 这种

    37 replies  •  2025-01-18 13:27:12 +08:00
    Leviathann
    Leviathann
    Dec 7, 2023
    1
    因为 rust 是 MozillaML
    xtreme1
    xtreme1
    Dec 7, 2023
    2
    rust 的 ? 运算符已经用于错误处理了, 像这样改会破坏现有的语义
    https://blog.rust-lang.org/2016/11/10/Rust-1.13.html#the--operator
    serco
    serco
    Dec 7, 2023❤️1
    3
    因为 Option 本来就是为了解决 nil/null 问题的

    你返回也是 Option 就可以链式调用,或者用 try_block
    hangbale
    hangbale
    Dec 7, 2023
    4
    我反倒觉得显式定义 Option 类型更加直观,类似的 Haskell 中也有 Maybe 类型
    gitrebase
    gitrebase
    Dec 7, 2023❤️1
    5
    首先支持 #2

    再说个可能的视角,Option 算是 FP 原生的 Monad 的概念吧,今天要是对 Option 这个 Monad 特殊处理了,那明天是不是要对 Result 也来个语法糖,后天再来个 Monad 是不是要再搞个语法糖,永无止尽
    TomatoCLI
    TomatoCLI
    Dec 7, 2023
    6
    你可以自己加
    monkeyWie
    monkeyWie
    OP
    Dec 7, 2023
    7
    @xtreme1 我懂你意思,但是语法糖可以换个符号嘛
    PTLin
    PTLin
    Dec 7, 2023
    8
    Option ,Result 实现了 Try trait ,增加了新手很多的理解成本。让这个类型更“特殊”,对于编译器的语法分析,还是代码的阅读都毫无帮助。
    kotlin ,dart 这么做很大程度上因为 null 是语言概念的一部分,而 Option 只是一个普通的类型,并无特殊的地方。
    imzcg2
    imzcg2
    Dec 7, 2023
    9
    ?这个问题有人认为简洁有人为奇怪什么东东。直接 option 包裹是最直白的
    imzcg2
    imzcg2
    Dec 7, 2023
    10
    你以为的优势别人吐槽的也不少
    Mistwave
    Mistwave
    Dec 7, 2023 via iPhone
    11
    因为 Option 远不只是?. ?:语法糖
    举个例子,我可以为 Option 实现 Foldable ,可以 traverse 、sequence
    hronro
    hronro
    Dec 7, 2023
    12
    @gitrebase Result 这个 Monad 已经被特殊处理了吧
    kkrainbow9966
    kkrainbow9966
    Dec 7, 2023
    13
    ```
    fn main() {
    let a = None;
    println!("{}", a.unwrap_or(0));
    }
    ```

    这样也可以吧,可以自动推导出类型
    yueqianzhang
    yueqianzhang
    Dec 7, 2023
    14
    因为 rust 有一个目标是直观无歧义, 方法重载都没有
    yueqianzhang
    yueqianzhang
    Dec 7, 2023
    15
    说错了 默认值..
    yueqianzhang
    yueqianzhang
    Dec 7, 2023
    16
    一个带多个问号的链式调用可能中间就中断了(虽然可以不这么写,但毕竟太灵活了没限制)
    rust 相当于提醒你要处理调用链的异常情况,起码搜索的时候搜 unwrap 好搜,你搜问号试试...

    还有可空类型本来是一个整体却要用两个分开的东西来表示感觉也怪怪的 (doge

    https://fengliang.io/RustWHY/design_choices/why_not_overloading.html
    yueqianzhang
    yueqianzhang
    Dec 7, 2023
    17
    问号不像一个严肃的系统编程语言用的,感觉风格不搭,Swift/Kotlin 这种风格用倒是挺符合
    mainjzb
    mainjzb
    Dec 7, 2023
    18
    纯属抄 C++抄过头了。。。
    gzlock
    gzlock
    Dec 7, 2023
    19
    先别管什么直不直白了
    经常要输入的内容搞得太长了,我是嫌烦的
    mainjzb
    mainjzb
    Dec 7, 2023
    20
    https://ziglang.org/documentation/master/#Optionals
    动态语言可能没有说服力,让我们看一下号称代替 C 的 zig ,同样支持符号化 option 。🙌
    monkeyWie
    monkeyWie
    OP
    Dec 7, 2023 via Android
    21
    @mainjzb 这个味就对了啊
    PrivateRookie
    PrivateRookie
    Dec 7, 2023❤️1
    22
    rust 的 Optional 是可以链式调用的啊, 而且 rust 一般都不怎么需要显示写类型, 直接类型推断就完事了, 你看这个例子里的变量赋值和 get_name 函数里的?用法
    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=80b17634d331937a2565315bd9a4f84d
    PrivateRookie
    PrivateRookie
    Dec 7, 2023❤️1
    23
    Option 作为普通类型的好处是可以方便地和 trait 结合, 比如这个例子就用 Into trait + Optional, 避免传参的时候多包一层 Some

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=56b2d9460341075d554afc8ca0ba0240
    blindinlights
    blindinlights
    Dec 7, 2023
    24
    一般都不会标注类型的,自动推导就行了,没必要搞个特殊的语法
    agagega
    agagega
    Dec 8, 2023
    25
    其实这个思路和 C++挺类似,就是加语法糖可以,但要想办法做得通用,得让用户自定义的类型也能用上。如果用问号代表 Option ,那就是一个定死的语法糖了。所以 Rust 里的问号是一个操作符,你可以实现 std::ops::Try 这个 trait 来自定义
    GuuJiang
    GuuJiang
    Dec 8, 2023❤️1
    26
    首先,rust 的 Option 也是可以使用?运算符链式调用的,只不过由于?优先设计给了 Result ,所以只有当一个代码块里没有出现过将?应用于 Result 的返回时才可以应用于 Option ,否则只要有了一处 Result ,同一个代码块里在 Option 的地方用?就会报错,因为这时候期望的也是 Result ,只要满足了这个条件,对 Option 使用?是完全没有问题的,示例如下
    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a4973d87ed8e4d19934952ccb10ce6c6
    上面所有认为 Option 没有?运算符并且还强行给出解释的未免有点先射箭再画靶了
    不过话说回来,由于上面的限制条件的存在,并且现实中 Result 大量存在,所以能对 Option 用上?操作符的机会确实不多,因为不管 Result 还是 Option 的?,都是为了“像写命令式一样写 FP”这个目的而存在,等你习惯了 if let 解构以后就会发现其实 if let 也挺真香的,到时候自然也不会想要什么?了
    ispinfx
    ispinfx
    Dec 8, 2023 via iPhone
    27
    类型放个问题实在太恶心
    ispinfx
    ispinfx
    Dec 8, 2023 via iPhone
    28
    号
    yueqianzhang
    yueqianzhang
    Dec 8, 2023
    29
    带问号的都有有 null/nil 概念,而 rs 变成了枚举的 case
    bianhui
    bianhui
    Dec 8, 2023
    30
    没什么不可以的,可以啊。只是加了,又有人会说,为什么搞得像快餐语法一样,这会让一部分人心里少了优越感。众口难调,只是没有调对你的口罢了
    monkeyWie
    monkeyWie
    OP
    Dec 8, 2023
    31
    @GuuJiang 那确实基本上用不了,只能用 and_then 来写了,好长一坨代码
    nebkad
    nebkad
    Dec 12, 2023
    32
    ? 语法糖仅仅用来表是可空真的是太浪费了
    lifespy
    lifespy
    Dec 14, 2023
    33
    @nebkad #32 我觉得如果代码很多地方都要判断是否空,那就是值得的
    nebkad
    nebkad
    Dec 14, 2023
    34
    @lifespy

    如果你是说代码的很多 **表示类型** 的地方都需要表达是否可空,嫌弃 Option 字母多,那你需要的可能是编辑器自动提示。

    如果你是说需要链式处理判断是否空,那也是我支持的语法糖作用,并且 Rust 也支持,你甚至还可以用 Try trait V2 来自定义衍生的语义。

    总的来说,OP 对 rust 了解太少,习惯或者麻木的东西太多
    caobug
    caobug
    Dec 21, 2023
    35
    太多 a?.b?.c 说明程序设计有问题,而且容易习惯用?取值。为避免歧义,我经常在 swift 中使用 a!.b 告诉阅读者这里不可能为空。
    IMXT
    IMXT
    Dec 25, 2023
    36
    Rust 的 Option 就是从 OCaml 抄过来的。OCaml 里面就是 Option 。
    lumyx
    lumyx
    Jan 18, 2025
    37
    糖多了就是容易滥用,rust 一把子掐断了,就是杜绝低级程序员的弱智行为。

    kotlin 语法糖很多,很灵活,但是没多少人能写出正常的 kotlin 代码。尤其是从 Android 转过来的,java 写习惯了。写到 kotlin 一堆 ? 。 写的人为了方便且避免 crash ,代码里一堆 a?.b?.c?.d?.e? 这种代码一旦出了问题。都不知道断在哪个 ?。如果强制用 Option, 方便和 避免 crash 不可兼得。为了方便,你只能 `a.unwrap().b.unwrap().` 强制 crash 。

    或者挨个 match 嵌套处理。 这样就倒逼开发者自己去保证上游哪些值一定不能为空。这样写起来就方便了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2110 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 74ms · UTC 16:23 · PVG 00:23 · LAX 08:23 · JFK 11:23
    ♥ Do have faith in what you're doing.