为什么我需要在数组之前使用星号?

我不知道这是一个哈希问题还是数组问题,但我不知道为什么在第三个例子中需要使用星号(*)来获得填充数据的哈希值。 没有它,它会输出一个空哈希。

# -*- coding: utf-8 -*- require 'pp' pp [[:first_name, 'Shane'], [:last_name, 'Harvie']] # => [[:first_name, "Shane"], [:last_name, "Harvie"]] pp [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten # => [:first_name, "Shane", :last_name, "Harvie"] pp Hash[*[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten] # => {:first_name=>"Shane", :last_name=>"Harvie"} pp Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten] # => {} 

以下是该方法的说明。

 --------------------------------------------------------------- Hash::[] Hash[ [key =>|, value]* ] => hash From Ruby 1.8 ------------------------------------------------------------------------ Creates a new hash populated with the given objects. Equivalent to the literal +{ _key_, _value_, ... }+. Keys and values occur in pairs, so there must be an even number of arguments. Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200} Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200} { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200} 

splat运算符(即* )将原本是数组的数组转换为散列内的赋值列表。 您必须为[]运算符指定一个实际列表,以转换为哈希的键/值对。 (请参阅下面的链接到splat运算符的简短描述,实际上可以执行此操作(将数组展开到列表中)或反向(将列表收集到数组中)。)

你在上面的方式,你给Hash[] 奇数个项目 ,即一个数组。 (想想[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten产生。它产生[:first_name, 'Shane', :last_name, 'Havie'] 。)作为文档你引用说, []运算符必须有偶数个元素。 请注意,以下(虽然无用) 确实有效:

 >> Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten, 1] => {[:first_name, "Shane", :last_name, "Harvie"]=>1} 

(我不清楚为什么你在使用上面的代码时没有得到“奇数个Hash参数”错误 – 正如你尝试使用Hash[1] 。)

一个更简单的例子可以使它更清楚。 首先,传入一个项目,一个数组。 用*打开数组来交给Hash[]一个项目列表:

 >> Hash[['foo', 'bar', 'bizz', 'buzz']] => {} >> Hash[*['foo', 'bar', 'bizz', 'buzz']] => {"foo"=>"bar", "bizz"=>"buzz"} 

有关更全面的解释,请参阅此博客文章 。 您可能还会发现关于splat运算符的这篇简短描述很有用。