2013-08-17 101 views

回答

276

Ruby 2.0引入了關鍵字參數,**的作用類似*,但用於關鍵字參數。它返回一個帶有鍵/值對的哈希表。

對於此代碼:

def foo(a, *b, **c) 
    [a, b, c] 
end 

這裏有一個演示:

> foo 10 
=> [10, [], {}] 
> foo 10, 20, 30 
=> [10, [20, 30], {}] 
> foo 10, 20, 30, d: 40, e: 50 
=> [10, [20, 30], {:d=>40, :e=>50}] 
> foo 10, d: 40, e: 50 
=> [10, [], {:d=>40, :e=>50}] 
+32

這回答了問題完美,但我有一個小附錄。正如可以在您傳遞的數組上使用splat運算符一樣,雙splat可以用於散列。如果'opts = {d:40,e:50}',那麼'foo 10,opts,f:60'會將'{f:60}'賦值給'c',而'foo 10,** opts,f :60'將分配'{d:40,e:50,f:60}'。爲了達到第二個效果,以前你會明確地合併數組。 – brymck

+0

我認爲這對設置方法的可選散列參數有用 – Edmund

+9

注意:如果你使用@ brymck的構造(至少在MRI Ruby 2.1.1中),行爲不是merge,而是merge, 'opts'現在將是'{d:40,e:50,f:60}'。然而,如果你反轉這些參數 - 例如'foo 10,c:30,** opts'將不會永久地將'c:30'添加到'opts',這是不正確的。我還沒有看到有關這種行爲的任何文件,我發現它非常令人驚訝。 –

30

這是雙圖示運營商是可用的,因爲紅寶石2.0。

它捕獲所有關鍵字參數(也可以是一個簡單的哈希,這是他們成爲了Ruby語言的一部分之前效仿關鍵字參數的慣用方式)

def my_method(**options) 
    puts options.inspect 
end 

my_method(key: "value") 

上面的代碼打印{key:value}到控制檯。

就像一個圖示操作捕捉所有的常規參數,但不是一個陣列你得到一個哈希

現實生活中的例子:

例如,在軌cycle方法是這樣的:

def cycle(first_value, *values) 
    options = values.extract_options! 
    # ... 
end 

這種方法可以這樣調用:cycle("red", "green", "blue", name: "colors")

這是一個相當常見的模式:您接受參數列表,最後一個是選項哈希,可以使用ActiveSupport的extract_options!進行提取 - 例如。

在Ruby 2.0可以簡化這些方法:

def cycle(first_value, *values, **options) 
    # Same code as above without further changes! 
end 

誠然,這只是一個小的改進,如果你已經使用的ActiveSupport但對於普通的Ruby代碼收益頗多簡潔。

-16

對於整數,**表示指數 即2 ** 3是一樣的2^3

+1

'^'是Ruby中的二進制XOR,所以'2^3!= 2 ** 3''但是'2^3 == 1' – yurko

+5

雖然這與問題似乎沒有關係。 –

6

此外,你可以用它在發送方是這​​樣的:

def foo(opts); p opts end 
bar = {a:1, b:2} 

foo(bar, c: 3) 
=> ArgumentError: wrong number of arguments (given 2, expected 1) 

foo(**bar, c: 3) 
=> {:a=>1, :b=>2, :c=>3}