PowerShell 5.1有人能解释一下散列表和splatting吗

qni6mghb  于 2023-02-04  发布在  Shell
关注(0)|答案(2)|浏览(128)

给定:
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

izj3ouym

izj3ouym1#

现有答案中包含了很好的信息,但让我尝试进行一个重点突出的总结:

    • 您的实际问题**的答案是:
  • 是的,@{ FirstName = 'John'; LastName = 'Smith' }也是一个hashtable,即声明性的hashtable * literal*的形式-就像@{}是一个 * empty * hashtable literal(它构造了一个最初没有条目的示例)。
  • 哈希表文本由零个或多个键值对组成,每个键值对用=分隔,键值对用;或换行符分隔。
  • 键通常不需要 * 引号 *(例如FirstName),除非它们包含特殊字符,例如空格,或者通过 * 表达式 * 提供,例如变量引用;详情请参见this answer
  • 这与稍后 以编程方式*向哈希表添加条目形成对比,正如$hashtable1.Add('PROD', ...)方法调用所示(其中PROD是条目 * key *,...是条目 * value * 的占位符)。
  • 注意,使用.Add()方法的一个更方便的替代方法是使用 * 索引表达式 * 或者甚至是 * 点符号*(类似于属性的访问),尽管注意它在情况下要么 * 添加 * 一个条目要么 * 更新一个现有条目 *:$hashtable1['PROD'] = ...$hashtable1.PROD = ...

您问题的 * 标题*所暗示的更广泛问题的答案:

  • 通过语法糖[ordered] @{ ... },即通过将[ordered]放置在哈希表文本之前,PowerShell提供了一个不区分大小写的 * 有序*字典,该字典维护条目定义顺序,并允许除了通常的基于键的访问之外还通过 * 位置 * 索引进行访问。这种有序哈希表是. NET System.Collections.Specialized.OrderedDictionary类型的不区分大小写的示例。
  • 举个简单的例子:
# Create an ordered hashtable (omit [ordered] for an unordered one).
$dict = [ordered] @{ foo = 1; bar = 'two' }

# All of the following return 'two'
$dict['bar'] # key-based access
$dict.bar    # ditto, with dot notation (property-like access)
$dict[1]     # index-based access; the 2nd entry's value.
      • Splatting是一种参数传递技术**,它**能够通过包含对参数进行编码的数据结构的 * 变量**间接*传递参数,这对于动态构造参数以及使具有许多参数的调用更具可读性非常有用。
    • 通常情况下 ,而且是可靠的--但仅在调用 * PowerShell * 命令时带有 * 声明的参数***--该数据结构是***哈希表***,其条目键必须与目标命令的参数的 * 名称 * 匹配(例如,键Path目标参数-Path),并且其条目值指定要传递的 * 值 *。
  • 换句话说:这种形式的splatting使用哈希表来实现传递 * named * arguments(参数值前面是目标参数的名称,例如 * direct * arguments传递中的-Path /foo)。
  • 举个简单的例子:
# Define the hashtable of arguments (parameter name-value pairs)
 # Note that File = $true is equivalent to the -File switch.
 $argsHash = @{ LiteralPath = 'C:\Windows'; File = $true }

 # Note the use of "@" instead of "$"; equivalent to:
 #   Get-ChildItem -LiteralPath 'C:\Windows' -File
 Get-ChildItem @argsHash
  • 可替换地,***数组***可用于展开,仅包括参数 * 值 *,然后将其 * 定位地 * 传递到目标命令。
  • 换句话说:这种形式的splatting使用数组来实现传递 * 位置 * 参数(参数 * 仅值 *)。
  • 此表单通常仅适用于:
  • 调用未正式声明参数的PowerShell脚本或函数时,通过自动$args变量访问其始终 * 按位置 * 的参数
      • 调用 * 外部程序***时;请注意,从PowerShell的Angular 来看,调用外部程序时没有 * named * 参数的概念,因为PowerShell对这种情况下的参数语法一无所知,所有参数都只是一个接一个地放在进程命令行中,由目标程序将它们解释为参数名称与值。
  • 举个简单的例子:
# Define an array of arguments (parameter values)
 $argsArray = 'foo', 'bar'

 # Note the use of "@" instead of "$", though due to calling an
 # *external program* here, you may use "$" as well; equivalent to:
 #   cmd /c echo 'foo' 'bar'              
 cmd /c echo @argsArray
u1ehiz5o

u1ehiz5o2#

@postanote有一些很好的关于哈希表和splatting的链接,是很好的读物。以你的例子为例,你有两个不同的函数。一个把哈希表作为参数处理,第二个只能处理一个字符串参数。哈希表不能用来把参数传递给第二个函数,例如:

PS C:\> Function2 $sel
Value: System.Collections.Hashtable

从概念上讲,使用哈希表和splatting之间的真实的区别不是如何使用它们向函数传递信息和参数,而是函数 * 及其 * 参数如何接收 * 信息**。
是的,某些函数可以使用哈希表和数组作为参数,但是,通常在98%的情况下,函数使用哈希表作为命名参数来获取其值。
例如,Copy-Item不使用哈希表作为参数。如果它使用哈希表,您是否希望在每次复制任何内容时都这样做:

$hashtable = @{
  Path = "C:\Temp\myfile.txt",
  Destination = "C:\New Folder\"
}
Copy-Item -Parameters $hashtable

不,相反,您希望参数为字符串,这样您就可以使它成为一个简单得多的一行程序:

Copy-Item -Path "C:\Temp\myfile.txt" -Destination "C:\New Folder\"

对大多数人来说,处理单个strings比传递一个通用的、大型的哈希表“config”更有意义。此外,通过将参数分隔为单独的字符串、整数、浮点数、字符等,也更容易进行验证、默认值、强制/非强制参数等。
尽管如此,在某些情况下,你有一些函数需要很多参数(例如发送一封邮件),或者你想多次执行某个操作(例如从CSV文件复制/移动很多文件),在这种情况下,使用哈希表和/或数组和/或哈希表数组会很有用。
这就是splating的用武之地。它接受一个哈希表,而不是像传递单个值那样处理它(例如,为什么Function2 $sel返回System.Collections.Hashtable),@符号告诉PowerShell它是一个值的集合,并使用该集合尝试匹配函数的参数。这就是为什么将哈希表传递给Function2不起作用,但是喷溅起作用,例如:

PS C:\> Function2 @sel
Value: John

在本例中,它获取哈希表$sel,通过使用splatting @sel,PowerShell现在知道不按原样传递哈希表,而是打开集合并将$sel.FirstName-Firstname参数匹配。

相关问题