V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
monkeyWie
V2EX  ›  Rust

最近初学 rust 有个疑问

  •  1
     
  •   monkeyWie · 2023-12-07 10:03:50 +08:00 · 4356 次点击
    这是一个创建于 387 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 这种

    36 条回复    2023-12-25 04:25:31 +08:00
    Leviathann
        1
    Leviathann  
       2023-12-07 10:29:32 +08:00
    因为 rust 是 MozillaML
    xtreme1
        2
    xtreme1  
       2023-12-07 10:29:46 +08:00
    rust 的 ? 运算符已经用于错误处理了, 像这样改会破坏现有的语义
    https://blog.rust-lang.org/2016/11/10/Rust-1.13.html#the--operator
    serco
        3
    serco  
       2023-12-07 10:31:05 +08:00   ❤️ 1
    因为 Option 本来就是为了解决 nil/null 问题的

    你返回也是 Option 就可以链式调用,或者用 try_block
    hangbale
        4
    hangbale  
       2023-12-07 10:45:34 +08:00
    我反倒觉得显式定义 Option 类型更加直观,类似的 Haskell 中也有 Maybe 类型
    gitrebase
        5
    gitrebase  
       2023-12-07 11:02:15 +08:00   ❤️ 1
    首先支持 #2

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

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

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

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

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=56b2d9460341075d554afc8ca0ba0240
    blindinlights
        24
    blindinlights  
       2023-12-07 23:33:58 +08:00
    一般都不会标注类型的,自动推导就行了,没必要搞个特殊的语法
    agagega
        25
    agagega  
       2023-12-08 00:36:52 +08:00
    其实这个思路和 C++挺类似,就是加语法糖可以,但要想办法做得通用,得让用户自定义的类型也能用上。如果用问号代表 Option ,那就是一个定死的语法糖了。所以 Rust 里的问号是一个操作符,你可以实现 std::ops::Try 这个 trait 来自定义
    GuuJiang
        26
    GuuJiang  
       2023-12-08 06:22:36 +08:00   ❤️ 1
    首先,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
        27
    ispinfx  
       2023-12-08 07:32:15 +08:00 via iPhone
    类型放个问题实在太恶心
    ispinfx
        28
    ispinfx  
       2023-12-08 07:32:22 +08:00 via iPhone
    yueqianzhang
        29
    yueqianzhang  
       2023-12-08 08:00:21 +08:00
    带问号的都有有 null/nil 概念,而 rs 变成了枚举的 case
    bianhui
        30
    bianhui  
       2023-12-08 08:23:50 +08:00
    没什么不可以的,可以啊。只是加了,又有人会说,为什么搞得像快餐语法一样,这会让一部分人心里少了优越感。众口难调,只是没有调对你的口罢了
    monkeyWie
        31
    monkeyWie  
    OP
       2023-12-08 09:40:57 +08:00
    @GuuJiang 那确实基本上用不了,只能用 and_then 来写了,好长一坨代码
    nebkad
        32
    nebkad  
       2023-12-12 02:54:47 +08:00
    ? 语法糖仅仅用来表是可空真的是太浪费了
    lifespy
        33
    lifespy  
       2023-12-14 10:08:56 +08:00
    @nebkad #32 我觉得如果代码很多地方都要判断是否空,那就是值得的
    nebkad
        34
    nebkad  
       2023-12-14 14:41:23 +08:00
    @lifespy

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

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

    总的来说,OP 对 rust 了解太少,习惯或者麻木的东西太多
    caobug
        35
    caobug  
       2023-12-21 13:26:10 +08:00
    太多 a?.b?.c 说明程序设计有问题,而且容易习惯用?取值。为避免歧义,我经常在 swift 中使用 a!.b 告诉阅读者这里不可能为空。
    IMXT
        36
    IMXT  
       2023-12-25 04:25:31 +08:00
    Rust 的 Option 就是从 OCaml 抄过来的。OCaml 里面就是 Option 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2650 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:04 · PVG 20:04 · LAX 04:04 · JFK 07:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.