rust 有空安全机制为什么不搞一套和 kotlin 和 dart 那样的空安全语法糖来替代手写 Option ,感觉写起来挺嗦的。
对比下:
// 声明可空 var number: Int? = null // 取值,为空时给默认值 number ?: 0
// 声明可空 int? number = null; // 取值,为空时给默认值 number ?? 0
// 声明可空 let number:Option<i32> = None; // 取值,为空时给默认值 number.unwrap_or(0);
可以看到 kotlin 和 dart 有语法糖写起来舒服多了,rust 为啥不支持下,写成这样:
let number:i32? = None; number ?? 0
当然还有更方便的链式调用,order?.user?.name
这种
1 Leviathann 2023-12-07 10:29:32 +08:00 因为 rust 是 MozillaML |
![]() | 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 |
![]() | 3 serco 2023-12-07 10:31:05 +08:00 ![]() 因为 Option 本来就是为了解决 nil/null 问题的 你返回也是 Option 就可以链式调用,或者用 try_block |
4 hangbale 2023-12-07 10:45:34 +08:00 我反倒觉得显式定义 Option 类型更加直观,类似的 Haskell 中也有 Maybe 类型 |
![]() | 5 gitrebase 2023-12-07 11:02:15 +08:00 ![]() 首先支持 #2 再说个可能的视角,Option 算是 FP 原生的 Monad 的概念吧,今天要是对 Option 这个 Monad 特殊处理了,那明天是不是要对 Result 也来个语法糖,后天再来个 Monad 是不是要再搞个语法糖,永无止尽 |
![]() | 6 cyrivlclth 2023-12-07 11:08:32 +08:00 你可以自己加 |
![]() | 8 PTLin 2023-12-07 11:38:30 +08:00 Option ,Result 实现了 Try trait ,增加了新手很多的理解成本。让这个类型更“特殊”,对于编译器的语法分析,还是代码的阅读都毫无帮助。 kotlin ,dart 这么做很大程度上因为 null 是语言概念的一部分,而 Option 只是一个普通的类型,并无特殊的地方。 |
![]() | 9 imzcg2 2023-12-07 13:44:10 +08:00 ?这个问题有人认为简洁有人为奇怪什么东东。直接 option 包裹是最直白的 |
![]() | 10 imzcg2 2023-12-07 13:44:38 +08:00 你以为的优势别人吐槽的也不少 |
![]() | 11 Mistwave 2023-12-07 15:10:35 +08:00 via iPhone 因为 Option 远不只是?. ?:语法糖 举个例子,我可以为 Option 实现 Foldable ,可以 traverse 、sequence |
13 kkrainbow9966 2023-12-07 18:37:06 +08:00 ``` fn main() { let a = None; println!("{}", a.unwrap_or(0)); } ``` 这样也可以吧,可以自动推导出类型 |
14 yueqianzhang 2023-12-07 18:54:46 +08:00 因为 rust 有一个目标是直观无歧义, 方法重载都没有 |
15 yueqianzhang 2023-12-07 18:55:35 +08:00 说错了 默认值.. |
16 yueqianzhang 2023-12-07 19:20:11 +08:00 一个带多个问号的链式调用可能中间就中断了(虽然可以不这么写,但毕竟太灵活了没限制) rust 相当于提醒你要处理调用链的异常情况,起码搜索的时候搜 unwrap 好搜,你搜问号试试... 还有可空类型本来是一个整体却要用两个分开的东西来表示感觉也怪怪的 (doge https://fengliang.io/RustWHY/design_choices/why_not_overloading.html |
17 yueqianzhang 2023-12-07 19:39:50 +08:00 问号不像一个严肃的系统编程语言用的,感觉风格不搭,Swift/Kotlin 这种风格用倒是挺符合 |
![]() | 18 mainjzb 2023-12-07 20:11:04 +08:00 纯属抄 C++抄过头了。。。 |
![]() | 19 gzlock 2023-12-07 20:19:13 +08:00 先别管什么直不直白了 经常要输入的内容搞得太长了,我是嫌烦的 |
![]() | 20 mainjzb 2023-12-07 20:32:36 +08:00 https://ziglang.org/documentation/master/#Optionals 动态语言可能没有说服力,让我们看一下号称代替 C 的 zig ,同样支持符号化 option 。 |
![]() | 22 PrivateRookie 2023-12-07 22:21:41 +08:00 ![]() rust 的 Optional 是可以链式调用的啊, 而且 rust 一般都不怎么需要显示写类型, 直接类型推断就完事了, 你看这个例子里的变量赋值和 get_name 函数里的?用法 https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=80b17634d331937a2565315bd9a4f84d |
![]() | 23 PrivateRookie 2023-12-07 22:25:23 +08:00 ![]() Option 作为普通类型的好处是可以方便地和 trait 结合, 比如这个例子就用 Into trait + Optional, 避免传参的时候多包一层 Some https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=56b2d9460341075d554afc8ca0ba0240 |
24 blindinlights 2023-12-07 23:33:58 +08:00 一般都不会标注类型的,自动推导就行了,没必要搞个特殊的语法 |
![]() | 25 agagega 2023-12-08 00:36:52 +08:00 其实这个思路和 C++挺类似,就是加语法糖可以,但要想办法做得通用,得让用户自定义的类型也能用上。如果用问号代表 Option ,那就是一个定死的语法糖了。所以 Rust 里的问号是一个操作符,你可以实现 std::ops::Try 这个 trait 来自定义 |
26 GuuJiang 2023-12-08 06:22:36 +08:00 ![]() 首先,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 也挺真香的,到时候自然也不会想要什么?了 |
27 ispinfx 2023-12-08 07:32:15 +08:00 via iPhone 类型放个问题实在太恶心 |
28 ispinfx 2023-12-08 07:32:22 +08:00 via iPhone 号 |
29 yueqianzhang 2023-12-08 08:00:21 +08:00 带问号的都有有 null/nil 概念,而 rs 变成了枚举的 case |
![]() | 30 bianhui 2023-12-08 08:23:50 +08:00 没什么不可以的,可以啊。只是加了,又有人会说,为什么搞得像快餐语法一样,这会让一部分人心里少了优越感。众口难调,只是没有调对你的口罢了 |
32 nebkad 2023-12-12 02:54:47 +08:00 ? 语法糖仅仅用来表是可空真的是太浪费了 |
34 nebkad 2023-12-14 14:41:23 +08:00 @lifespy 如果你是说代码的很多 **表示类型** 的地方都需要表达是否可空,嫌弃 Option 字母多,那你需要的可能是编辑器自动提示。 如果你是说需要链式处理判断是否空,那也是我支持的语法糖作用,并且 Rust 也支持,你甚至还可以用 Try trait V2 来自定义衍生的语义。 总的来说,OP 对 rust 了解太少,习惯或者麻木的东西太多 |
35 caobug 2023-12-21 13:26:10 +08:00 太多 a?.b?.c 说明程序设计有问题,而且容易习惯用?取值。为避免歧义,我经常在 swift 中使用 a!.b 告诉阅读者这里不可能为空。 |
36 IMXT 2023-12-25 04:25:31 +08:00 Rust 的 Option 就是从 OCaml 抄过来的。OCaml 里面就是 Option 。 |
37 lumyx 267 天前 糖多了就是容易滥用,rust 一把子掐断了,就是杜绝低级程序员的弱智行为。 kotlin 语法糖很多,很灵活,但是没多少人能写出正常的 kotlin 代码。尤其是从 Android 转过来的,java 写习惯了。写到 kotlin 一堆 ? 。 写的人为了方便且避免 crash ,代码里一堆 a?.b?.c?.d?.e? 这种代码一旦出了问题。都不知道断在哪个 ?。如果强制用 Option, 方便和 避免 crash 不可兼得。为了方便,你只能 `a.unwrap().b.unwrap().` 强制 crash 。 或者挨个 match 嵌套处理。 这样就倒逼开发者自己去保证上游哪些值一定不能为空。这样写起来就方便了。 |