PowerShell 中 function 返回值的陷阱

問題描述

PS 中的 function 使用起來很是自由,但它會對返回值作一種奇怪的處理。html

咱們一塊兒來看下面這段代碼,你認爲這個 function 的返回值是什麼類型?shell

function TestReturn () {
  $ls = [System.Collections.Generic.List[int]]::new()
  $ls.Add(1)
  return $ls
}
$(TestReturn).GetType()

喂!這怎麼看都是返回了一個 List<int> 吧?函數

可是你運行以後獲得的結果是這樣的:spa

啊!!!我 List<int> 呢???.net

而後當咱們「天真地」將這個返回值看成一個 List<int> 使用時,大概會獲得一個:設計

「Method invocation failed because [System.Int32] does not contain a method named 'xxx'.」code

緣由分析

不止 List<int> 會這樣, Queue<int> 以及其餘經常使用的泛型/非泛型集合、甚至 Array 都是副德性……那咱們大概能夠進一步推測:全部 collection 都是這德性(歡迎讀者驗證並評論)。htm

具體緣由不明,大概只有 PS 的設計者能解釋了吧。ip

我推測與它對於多個返回值的處理有關(http://www.pstips.net/powershell-specify-return-value-from-function.html),這個設計的邏輯感受就像是:ci

「多個返回值變成一個 Object[],只包含一個 item 的 collection 返回值會變成一個 item」

前者顯然是有好處的,但我看不到後者的意義,但願知情者能在評論區解釋一下,感激涕零!

解決方案

我仍是但願獲得一個 collection(返回的類型與 collection 的 Count 相關什麼的真是太扯了)。

因此對於這種畫蛇添足的設計,我選擇使用 PS 強大的類型轉換(http://www.pstips.net/powershells-type-conversion-magic.html)解決:每當調用的函數可能返回一個僅包含一項的 collection 時,經過強制類型轉換獲得預期的 collection 類型

$tr = [System.Collections.Generic.List[int]]$(TestReturn)

固然,你也能夠選擇 Foreach-Object 這樣強大的 cmdlet,這樣就沒必要糾結它是 item 仍是 collection 了,也許這樣更符合 PS 設計者的初衷?

相關文章
相關標籤/搜索