2010-05-06 146 views
77

_=> expr這樣的lambda表達式是什麼意思?_ =>這在Lambda表達式中意味着什麼?

_作爲lambda輸入的目的是什麼?

例子:

int sum = 0; 
list.ForEach(_=> { sum += 1; }); 
+5

嗨,歡迎來到StackOverflow。我冒昧地修改你的問題以增加獲得有用答案的機會,希望你不介意。 – 2010-05-06 04:12:56

+0

請注意,假設'list'是一個'IEnumerable ',他們可以*(並且應該)*剛剛使用了'sum = list.Count();' – 2011-10-24 19:01:51

回答

58

這是一個慣例,當你不關心的參數使用。

+1

這是* a *約定,而不是所有人使用的。 – Bevan 2010-05-06 04:10:46

+3

它在Haskell和其他函數式語言中更常見。我認爲這是它的來源。 – 2010-05-06 04:34:03

+7

在Haskell,ML,Scala等中,'_'是模式匹配中的通配符。它基本上意味着「我不在乎,我總是*想要這樣匹配」。這個「我不在乎」然後被轉移到*命名*的東西,你不關心,從那裏,它溢出到其他編程語言。例如,在Ruby中也用於表示與此示例中相同的內容,即使'_'在Ruby中絕對沒有特別的意義。 – 2010-05-06 05:33:07

22

_是一個有效的變量名稱。他們只是使用_作爲變量。

35

這是一個參數的名字,雖然不是一個有用的一個,但它通常使用(由一些約定)當您需要指定表達爲了讓代碼編譯參數之一,但你並不關心它,所以你會忽略它。

它基本上是利用C#中的合法標識符構成的語法,並且由於標識符可以以下劃線開始,並且不包含任何其他內容,所以它只是一個參數名稱。

你可能只是很容易地採寫:

var _ = 10; 
+1

而不是_,我們可以使用()嗎? – amesh 2015-01-03 11:45:44

+2

你嘗試過使用它嗎? – 2015-01-03 11:46:11

+0

是的,我在使用lambda表達式創建線程時使用了它。 'Thread t = new Thread(()=> doSomething(x,y)); t.start();' – amesh 2015-01-03 12:03:11

9

因爲LAMDA表達在很短的,匿名的代碼大多采用這樣的變量的名稱有時時並不需要,甚至不使用變量在代碼塊中,所以他們只給出一個短的,傳統

3

我還第二次使用_ => _.method()單線,方法調用lambdas,因爲它減少了指令的認知權重。特別是在使用泛型時,寫作x => x.method()只是增加了「這是什麼x'的分秒考慮?它是空間座標嗎?」。

考慮以下情況:

Initialize<Client> (_=>_.Init());

使用一個泛型呼叫,在這種情況下,下劃線工程作爲「繞過標誌」。它避免冗餘,定義參數的類型是顯而易見的,並且可以從使用中引發 - 就像當您使用「var」來防止重複類型聲明一樣。在這裏編寫client=>client.Init()只會使指令更長,而不會增加任何含義。

顯然,這不適用於要傳遞給該方法的參數,應該將其命名爲描述性的。例如:Do(id=>Log(id));

由於lambda標識符與其泛型定義斷開連接,因此在使用代碼塊而不是單線時,方法調用的單下劃線參數用法難以合理。一般情況下,如果要重複使用相同的標識符,請爲其指定一個描述性名稱。

底線是冗長只適用於消歧,特別是對於創建簡化匿名代理創建的lambda。無論如何,應該使用常識,平衡易讀性和簡潔性。如果符號只是真正的功能的「鉤子」,那麼一個字符標識符就非常好。 For循環和「i」和「j」字母就是索引器。

+1

+1這種方法!雖然我是唯一一個在lambda中使用下劃線來「減少認知權重」而不是顯示這個參數沒有被使用的人。它用下劃線讀起來更容易,特別是如果有很多鏈接,並且可以立即推斷出類型,就像LINQ查詢經常發生的那樣! – 2017-06-23 21:10:23

+0

'Do(id => Log(id))'最好縮寫爲'Do(Log)'。 – 2017-08-05 11:29:41