2011-12-31 68 views
7

當存在不被使用的塊或局部變量,有時人們*標記它,以及有時與_標記的未使用的塊變量

{[1, 2] => 3, [4, 5] => 6}.each{|(x, *), *| p x} 

{[1, 2] => 3, [4, 5] => 6}.each{|(x, _), _| p x} 

{[1, 2, 3], [4, 5, 6]}.each{|*, x, *| p x} 

{[1, 2, 3], [4, 5, 6]}.each{|_, x, _| p x} 

def (x, *), *; p x; end 

def (x, _), _; p x; end 

def *, x, *; p x; end 

def _, x, _; p x; end 

它們之間有什麼區別,什麼時候應該用哪個?如果需要將多個變量標記爲未使用,那麼要麼更好?

回答

26

A *表示「所有剩餘參數」。 _只是另一個變量名稱,儘管它有點特別。因此,他們是不同的,例如下面的無厘頭:

[[1, 2, 3], [4, 5, 6]].each{|*, x, *| p x} # Syntax error 

事實上,如何紅寶石應該知道如果第一個明星應該得到的值(和反向)的0,1或2?

很少有情況下,您想使用星號來忽略參數。一個例子是,如果你只想使用的參數變量號的最後:

紅寶石讓你不給參數的「休息」起一個名字,但你可以使用_

[[1], [2, 3], [4, 5, 6]].each{|*_, last| p last} # => prints 1, 3 and 6 

通常,參數的數量是已知的,您最好的選擇是使用_

[[1, 2, 3], [4, 5, 6]].each{|_, mid, _| p mid} # prints 2 and 5 

注意,你可以離開的最後paramater烏納MED,雖然它是不太明顯的過(當使用一個*狀即可):

[[1, 2, 3], [4, 5, 6]].each{|_, mid, | p mid} # prints 2 and 5 

現在_使用,當你不希望使用的值指定變量名。這有兩個原因一個特殊的變量名:

  1. ,如果你不使用它(如果警告是上)紅寶石不會抱怨
  2. 紅寶石將允許您重複它在參數列表中。點1的

實施例:

> ruby -w -e "def foo; x = 42; end; foo" 
-e:1: warning: assigned but unused variable - x 

> ruby -w -e "def foo; _ = 42; end; foo" 
no warning 

點2的實施例:

[[1, 2, 3], [4, 5, 6]].each{|unused, mid, unused| p mid} 
# => SyntaxError: (irb):23: duplicated argument name 

[[1, 2, 3], [4, 5, 6]].each{|_, mid, _| p mid} 
# => prints 2 and 5 

最後,如@DigitalRoss筆記,_保持最後的結果在irb

更新:在Ruby 2.0中,您可以使用任何以0123開頭的變量來表示它是未使用的。通過這種方式,變量名可以更加明確被忽視了:

_scheme, _domain, port, _url = parse_some_url 
# ... do something with port 
+0

感謝您的詳細解答。這個答案有我想要的所有信息。 – sawa 2012-01-01 04:25:36

1

我認爲這主要是文體和程序員的選擇。在Ruby中使用*對我來說更有意義,因爲它的目的是累積從該位置向前傳遞的所有參數。 _是一個很難在Ruby中看到的退化變量,我聽說過它需要消失的意見。所以,如果我要使用,我會使用*

有的公司可能會在他們的編程風格文檔中定義它,如果他們有一個,但我懷疑這是值得他們大部分時間,因爲它是一個拋棄變量。我從事專業研發超過20年,從未見過任何可以拋棄的命名。

就個人而言,我不擔心這個,我會更關心的是使用單字母變量。爲了這個目的,我將使用unusedvoidblackhole

+3

'_'是*不*要離開,並有具體的治療,看到我的回答。此外,在警告中運行Ruby可能會在使用'unused'或simial時給你警告,而不是'_';請參閱我的回答;-) – 2012-01-01 03:58:01

1

它們之間有什麼區別?

_的情況下,正在創建局部變量_。這就像使用x但命名不同。

*情況下的表達式來*分配創建[expression]。我不太清楚它有什麼用處,因爲它似乎沒有用括號括起來表達任何事情。

當我應該使用哪一個?

在第二種情況下,您最終不會創建額外的符號,但它對於解釋器來說看起來稍微複雜一些。另外,很明顯,你永遠不會使用這個結果,而對於_,你將不得不讀取循環來知道它是否被使用。

但我預測你的代碼的質量將取決於比招你用它來擺脫未使用塊參數的其他事情。 *確實有一些我不太喜歡的冷酷因素。

注意:實驗時,請注意,在irb中,_保留最後一個表達式的值。

+0

你的意思是'**'的情況下,還是'*'?我的意思是'*',但它們有什麼不同?我知道用'*'作爲創建一個數組的時候,前綴是變量名,但是'*'的使用是相同的嗎?在主環境中,如果我鍵入'* = ['a']',它會返回'['a']'。那是什麼意思? – sawa 2011-12-31 18:37:56

1

國際海事組織的做法使代碼更不可讀,並不太明顯。

特別是在API的方法以阻止它可能不是很清楚什麼模塊實際上期望。這故意從源頭中刪除信息,使維護和修改更加困難。

我寧願變量被正確命名;在一個很短的塊中,它顯然沒有被使用。在較長的時間段內,如果不使用非常明顯,評論可能會詳細說明原因。