Ruby Ruby 中为何不支持列表构造

lilijreey · 2018年10月15日 · 最后由 bysxiang 回复于 2018年10月22日 · 2224 次阅读

在 python,erlang 等语言中都有列表构造,功能强大切可读性高。为何 ruby 没有支持。

[x +1 for y]

你说 foo *[1, 2, 3]

是指 destructuring assignment(解构赋值)吧,可以在 Ruby 社区搜索一下

https://bugs.ruby-lang.org/issues/8895#note-17

The proposed syntax is much harder to implement than it looks. It conflicts with Hash literals. As a result, humans can be confused as well.

Probably this kind of problems should be addressed by pattern matching, which we are considering to add to Ruby in the future.

Matz.


Update: 只有 Hash 解构不支持,数组是支持的

list = [ 0, 1, 2 ]
a, b, c = list

列表解构是有的,倒是 hash 解构没有

列表支持,hash 没有

没觉得有必要

解构的话,就是这种

h = {:a => 1}
{:a = a } = {:a => 1}

不如 h[:a],如果是对象的话,直接 h.a 就可行。

Erlang 不解构就太长了,比如 State#state.a,写起来麻烦。解构的话,方法定义又很长,读起来也麻烦,要高清从哪解出来的,要去读方法定义。

Erlang 的解构有 pattern matching,Clojure 一解构的时候,我就搞不清,到底有没有这个字段。

Erlang pattern matching 可以把依赖写成这种,括号比 Clojure 都晕。

{deps,
 [{xxx, {git, "git://github.com/xxx/xxx.git", {branch, "master"}}}]}

不如一个一个赋值来的简单易读

模式匹配吧,看看 elixir,太方便了

Ruby 有 Enumerable 和 block 语法,所以不需要增加列表构造这个语法。python 的 lambda 只能一行所以经常用列表构造而非 map 等函数

除了@jjym,楼上诸位的答案都跑偏了。

楼主说的应该是列表生成式,不过示例代码并不完整,推断代码应该是[x + 1 for x in [1,2,3]],其实就是把 for in 语句写在一行里,再省略了列表容器 (python 的列表相当于 ruby 中的数组)。这段 py 代码等价于 ruby 中的[1,2,3].map{|x| x+1}

更复杂的列表生成式[m + n for m in 'XY' for n in 'AB'],实际上就是个嵌套的 for in 循环,结果是 ['XA', 'XB', 'YA', 'YB'],用 ruby 写出来是'XY'.chars.product('AB'.chars).map(&:join)(可能有更优雅的写法)。

如同@jjym所说,ruby 中的枚举方法和 block 可以实现列表生成式的效果。个人认为这种语法在 ruby 中显得不那么面向对象,毕竟 ruby 一直倡导使用 each 等枚举方法来替代 for in 语句。相信有很多人都没有在 (或者极少在)ruby 中使用 for in。

spike76 回复

厉害,但是感觉列表构造,虽然不那么面向对象,但是很方便,易读。类似于一种 DSL, 希望 ruby 能够支持下。

@spike76 因为楼主更新了帖子,一开始并没有举例,而且问的是“列表解构”。

gaotongfei 回复

原来如此。我就很奇怪为什么会有这么多人跑偏。也看不到问题编辑历史。。。

symbol key 的 hash 也可以解构吧

楼主天天这么多问题😂

需要 登录 后方可回复, 如果你还没有账号请 注册新账号