我用的是PowerShell 5.1。
我在理解哈希表和splatting时遇到了麻烦。splatting是使用哈希表来实现的,还是完全不同的东西?
下面的代码:
$hashtable1 = @{}
$hashtable1.add('PROD',@{ FirstName = 'John'; LastName = 'Smith'})
function Main() {
$sel = $hashtable1['PROD']
Function1 $sel
Function2 @sel
}
function Function1([hashtable] $x) {
"Value: $($x.LastName)"
$x.FirstName
}
function Function2([string] $firstName) {
"Value: $($firstName)"
}
Main
2条答案
按热度按时间5fjcxozz1#
在现有的答案中有很好的信息,但让我尝试一个集中的总结:
您的实际问题的答案是:
@{ FirstName = 'John'; LastName = 'Smith' }
也是一个hashtable,即声明性的hashtable literal的形式-就像@{}
是一个 empty hashtable literal(它构造了一个最初没有条目的示例)。=
将每个键与其值分隔开,并使用;
或换行符分隔。FirstName
),除非它们包含特殊字符,例如空格,或者通过 * 表达式 * 提供,例如变量引用;详情请参见this answer。$hashtable1.Add('PROD', ...)
方法调用所示(其中PROD
是条目 key,...
是条目 value 的占位符)。.Add()
方法的一个更方便的替代方法是使用 index expression 或甚至 dot notation(类似于属性的访问),但请注意,它可能会根据情况 * 添加 * 一个条目或 * 更新一个现有条目 *:$hashtable1['PROD'] = ...
或$hashtable1.PROD = ...
您的问题 * 标题***所暗示的更广泛问题的答案:
PowerShell的hashtables是一种数据结构,通常称为dictionary or, in other languages, associative array or map。具体来说,它们是.NET
[hashtable]
(System.Collections.Hashtable
)类型的不区分大小写示例,该类型是无序 * 键值对条目的集合。哈希表支持通过关联键高效查找值。[ordered] @{ ... }
,即通过将[ordered]
放在哈希表文字之前,PowerShell提供了一个大小写不敏感 * 有序*字典,该字典维护条目定义顺序,并允许通过 * 位置 * 索引进行访问,除了通常的基于键的访问。这种有序哈希表是.NETSystem.Collections.Specialized.OrderedDictionary
类型的大小写不敏感示例。Splatting是一种参数传递技术,它**通过包含参数编码数据结构的 * 变量*间接传递参数,这对于动态构造参数和使具有许多参数的调用更具可读性非常有用。
Path
目标参数-Path
),并且其条目值指定要传递的 * 值 *。-Path /foo
)。$args
变量访问其始终 * 位置 * 参数时调用 * 外部程序时;注意,从PowerShell的Angular 来看,在调用外部程序时没有 named 参数的概念,因为PowerShell对这种情况下的参数语法一无所知,所有参数都只是一个接一个地放在进程命令行上,并且由目标程序将它们解释为参数名称与值。
fnx2tebb2#
@postanote有一些关于哈希表和splatting的非常好的链接,是很好的读物。以你的例子为例,你有两个不同的函数。一个处理哈希表作为参数,第二个只能处理单个字符串参数。哈希表不能用来向第二个函数传递参数,例如:
从概念上讲,使用哈希表和splatting之间的真实的区别不是如何使用它们向函数传递信息和参数,而是函数 * 和它们的 * 参数如何接收 * 信息**。
是的,某些函数可以使用哈希表和数组作为参数,但是,通常在98%的情况下,函数不使用哈希表作为命名参数来获取其值。
例如,
Copy-Item
不使用哈希表作为参数。如果它使用哈希表,您是否希望在每次复制任何内容时都这样做:不,相反,你希望参数是字符串,这样你就可以使它成为一个更容易的一行程序:
对于大多数人来说,处理单个的
strings
比传递一个通用的、大的、散列表的“配置”更有意义。此外,通过将参数分离为单独的字符串、整数、浮点数、字符等,也更容易进行验证、默认值、强制/非强制参数等。现在,尽管说了这么多,但有一种情况是,你有一些带有很多参数的函数(例如发送电子邮件),或者你想多次做一些事情(例如从CSV文件中复制/移动很多文件)。在这种情况下,使用哈希表和/或数组和/或哈希表数组将是有用的。
这就是splating的用武之地。它接受一个哈希表,而不是像传递单个值那样对待它(例如,为什么
Function2 $sel
返回System.Collections.Hashtable
),@
符号告诉PowerShell它是一个值的集合,并使用该集合尝试匹配函数的参数。这就是为什么将哈希表传递给Function2
不起作用,但溅射起作用,例如:在这种情况下,它接受哈希表
$sel
,通过使用splatting@sel
,PowerShell现在知道不按原样传递哈希表,而是打开集合并将$sel.FirstName
匹配到-Firstname
参数。