Ruby 2.0 double splat (**) 的一些用法

luikore · 2013年03月15日 · 最后由 torvaldsdb 回复于 2017年03月02日 · 4884 次阅读

double splat 除了可以在方法定义中简化 opts 外, 还可以用来组装 hash, 以后可以少写几个 merge 了:

h1 = {a: 1}
h2 = {b: 2}
h3 = {**h1, c: 3, **h2} #=> {:a=>1, :c=>3, :b=>2}

后放入的项会覆盖前面的项

h3 = {**h3, a: 'rewritten'} #=> {:a=>'rewritten', :c=>3, :b=>2}

任何实现了 to_ary 方法的对象都可以用 splat, 任何实现了 to_hash 方法的对象都可以 double splat:

class S < Struct.new :a, :b
  alias to_hash to_h
end
s = S.new 1, 2 #=> #<struct S a=1, b=2>
{**s} #=> {:a=>1, :b=>2}

特殊情况: 如果生成只包含 1 个 hash 的数组, 用 double splat 可以省一个大括号...

[**s, :a=>3]

这个暂时还不能用于 mass assignment

P.S. 要注意保持良好的代码 空格:

def f **x;end
h = {}
f **h # 双打散 :)
f\
**h3 # 双打散 :)
f** h # 阶乘 :(
f ** h # 阶乘 :(
f**h # 阶乘 :(

规则就是:

  • 方法名后无空格紧接 **, 就是阶乘
  • 要 double splat 时, ** 后不能带空格

[**s, a=>3] 应该是 [**s, :a=>3]

#2 楼 @luikore

双打散, 听着很搞怪呀~~ 我把作为形参的 splat 叫做 数组化 , 所以这个 double splat , 叫做 哈希化 也不错.

233 一个星是数组 两个星是哈希 理解了。不知道到了 3.0 之后是不是还会出来个三个星的。 不理解为什么放着那么多符号不选,偏偏选两颗星呢

跟 python 差不多

哭了,又一个坑啊

奇怪的功能还是少用,不然半年后,自己都看不懂了啊

#7 楼 @sevk 用习惯了,也就不奇怪了...

类似{"a" => "b"}这种 hash 不能被 **hash。。

TypeError: wrong argument type String (expected Symbol)

偶然遇到的单星

valid_keys = [:mass, :velocity, :time]
search(options.slice(*valid_keys))

如果单纯的search(options.slice(valid_keys))就会报错ArgumentError: wrong number of arguments (2 for 1)1

另附值得一看的十个小技巧

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