PowerShell 中 function 返回值的陷阱

问题描述

PS 中的 function 使用起来非常自由,但它会对返回值做一种奇怪的处理。

我们一起来看下面这段代码,你认为这个 function 的返回值是什么类型?

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

喂!这怎么看都是返回了一个 List<int> 吧?

但是你运行之后得到的结果是这样的:

092945_HZa0_3320818.png

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

然后当我们“天真地”将这个返回值当作一个 List<int> 使用时,大概会得到一个:

“Method invocation failed because [System.Int32] does not contain a method named 'xxx'.”

原因分析

不止 List<int> 会这样, Queue<int> 以及其他常用的泛型/非泛型集合、甚至 Array 都是副德性……那我们大概可以进一步推测:所有 collection 都是这德性(欢迎读者验证并评论)。

具体原因不明,大概只有 PS 的设计者能解释了吧。

我推测与它对于多个返回值的处理有关(http://www.pstips.net/powershell-specify-return-value-from-function.html),这个设计的逻辑感觉就像是:

“多个返回值变成一个 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 设计者的初衷?

转载于:https://my.oschina.net/u/3320818/blog/1512633

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值