Rust 可组合性比较差


我爱锈。我希望他们能花更多时间让它真正适用于非 hello-world 用例。

迭代
Rust 有一个很好的迭代语法:

for x in &mut something {
    *x = (*x) * 2;
}

除非你需要对迭代器做任何其他事情,否则它很丑陋:

for (i, x) in something.iter_mut().filter(|| {...}).enumerate() {
    *x = (*x) * i
}

如果它只适用于最简单的情况,那么拥有“漂亮”语法的意义何在?

我讨厌只适用于 hello world 示例的语法。这让我很生气,因为这意味着这一切都只是奥兹国,你最终需要拉开帷幕,而你所承诺的一切都是谎言。

Err
Rust 有一个很好的语法来提前返回Err案例。

let thing: Result<A, B> = x.foo();
// Will return early with the error if x.foo() returns Err.
let thing: A = x.foo()?;

但是当您尝试将它与迭代器一起使用时——这也很棒,我喜欢使用迭代器——它不起作用。

// ? in an Iterator method doesnt work!! What the hell!
let res: Vec<_> = iterator.iter().map(|x| x.foo()?).collect();

所以我们需要使用丑陋的 for-loop 手动集合

let res = vec![];
for x in &iterator {
    res.push(x.foo()?);
}

在我看来,for循环语法应该是iterator.iter().for_each(BODY)的简单语法糖,而不是定制语法。这打破了我的思维模式。拥有两个具有不同属性的完全不同的迭代语法有什么意义?

但这也发生在其他地方,因为这种丑陋的顽固性,我们不能这样做:

let z = x.foo().map(|y| y.bar()?);

我们必须做

let z = if let Some(y) = x.foo() {
    y.bar()?
}

应该有一种——最好只有一种——显而易见的方法来做到这一点。

同样,绝对缺乏可组合性是令人震惊的。如果你不能把迭代器方法用于现实世界中的用例,甚至还有什么意义呢?

异步
这基本上和之前的问题一样,需要用.await替代?,如果你想使用.await,你必须使用for循环语法,因为迭代器的功能不足以支持现实世界的使用情况。

结论
我成为Rust的粉丝已经10年了(哇!),我喜欢它。但是从事语言设计的团队需要放慢脚步,专注于人机工程学和可组合性。而不是因为其他语言有新的语法而增加新的语法。多年来,一直有人呼吁Rust的 "休眠fallow年",我认为这应该发生。当然,有这么多人在研究Rust,让每个人都去研究 "人体工程学 "是不可行的,但我认为这至少应该是一个重点。