PowerShell 中 function 返回值的陷阱


声明:本文转载自https://my.oschina.net/u/3320818/blog/1512633,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

问题描述

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

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

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

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

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

啊!!!我 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 设计者的初衷?

本文发表于2017年08月18日 12:36
(c)注:本文转载自https://my.oschina.net/u/3320818/blog/1512633,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2158 讨论 2 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1