相当于powershell中的local,测试一个元素是否包含在一个数组中

the equivalent of local in powershell, test if an element is contained in an array

我想要在 PowerShell 中等效于此代码

function containsElement () {
  local e
  for e in "${@:2}"; do [[ "$e" == "" ]] && return 0; done
  return 1
}

请帮帮我

您不需要 PowerShell 中的函数,因为它带有 collection-containment operators
-contains-in(它们的区别仅在于数组是否继续左轴或右轴):

# Sample value to test.
$element = 1

# Sample array to test against.
$array = 5, 3, 2, 1, 6

# Test if the value is in the array.
$contains = $element -in $array

# output the value of $contains
$contains

以上结果如预期的那样 True$true 的输出表示)。

警告:与传统的 shells 不同,PowerShell 具有基于 .NET 的 rich 类型系统,这意味着(隐含的)相等比较可能并不总是按预期工作;简而言之,由于自动类型转换,比较中操作数的顺序很重要,因此 '0xa' -in 10, 'other'$true,但 10 -in '0xa', 'other' 不是 - 请参阅 [=60= 的底部部分] 了解详情。


如果您确实需要使用作为 单独参数传递的数组元素复制 Bash 函数:

function containsElement {
    # Save the 1st argument passed and the remaining ones
    # in separate local variables, using a destructuring assignment.
    # $args is an automatic variable that contains the arguments
    # passed as an array ([object[]]), akin to $@ in Bash.
    $e, $arr = $args
    # Test, and implicitly output the Boolean result.
    $e -in $arr
}

# Sample call, equivalent of above.
containsElement 1  5 3 2 1 6

另请注意,PowerShell 将布尔值作为 数据(隐式或显式 [bool] 值)进行通信,而不是通过 不可见的状态信息(退出代码)POSIX-like shell 的方式,例如 Bash - 请参阅 的底部部分以获取更多信息。


PowerShell 中的局部变量与 POSIX-like shell 中的局部变量(例如,Bash)

上面函数中的

$e$arr局部变量,隐式如此;如果你想让这个事实明确,你可以使用 $local:e, $local:arr = $args,但这从来都不是必需的,因为 分配给 PowerShell 中的一个变量 隐含地和不变地 在本地(当前)范围内创建它

这不同于POSIX-likeshells,其中赋值没有local 修改 parent范围中预先存在的变量] 或者,如果存在 none, 会在 top-level(脚本)作用域[=137 中隐式创建变量=][1]:

  • 如 POSIX-like shells,PowerShell 中的 后代 作用域(child 作用域和他们的 children...) 做 see 局部变量 .

    • 不同于POSIX-like shells(ksh[1]除外),PowerShell还提供了一种方法创建一个真正的本地变量,即一个仅在定义范围内可见且可修改的变量,即通过$private: scope 修饰符:$private:var = 'truly local'[2].
      范围为 $private 的变量具有您对 词法 范围编译编程语言(例如 C#)中的局部变量所期望的有效行为(相对于 动态 作用域脚本语言)。
  • 与 POSIX-like shells 不同,后代作用域不能 修改 调用者的局部变量 不合格赋值 - 或任何祖先作用域的变量,就此而言。

    • 但是,PowerShell 提供显式 访问祖先范围,即通过 $script:$scope: 范围说明符 ,以及通过 Get-VariableSet-Variable cmdlet 的 -Scope 参数

有关 PowerShell 作用域规则的详细信息,请参阅 的底部部分。


[1] POSIX-like shells

中的范围界定演示

以下脚本适用于 bashdashzshbashdash 经常用作系统默认值 shell, /bin/sh).

要在 ksh 中创建脚本 运行,您必须将 local 关键字替换为 typeset 并使用 [=45= 定义函数] 关键字(function a { ... 而不是 a() { ...),因为 ksh 不理解 local 并且只使用 function 语法创建局部变量。
然而,与提到的其他 POSIX-like shells 不同,ksh 然后创建一个 真正的本地 变量,在后代范围中看不到,与 PowerShell 的 $private: 作用域是;换句话说:本地 ksh 变量 总是 function-local,后代作用域 永远不会 看到它们。

#!/usr/bin/env bash

a() {
  local var='1' # create local variable.
  echo "  calling scope before: [$var]"
  b # call function b
  echo "  calling scope after:  [$var]"
}

b() {
  echo "    child scope before:   [$var]" # calling scope's var. is visible
  var='1a' # modifies the *caller's* var.
  local var=2
  var='2a'  # modifies the *local* var.
  echo "    child scope after:    [$var]"
  newvar='hi' # assigning to a variable that doesn't exist in any scope
              # on the call stack creates it in the *top-level*  scope.
}

# Call function a()
a

# var. created in b() without `local` is now visible.
echo "script scope: [$newvar]"

这会产生以下结果:

  calling scope before: [1]
    child scope before:   [1]
    child scope after:    [2a]
  calling scope after:  [1a]
script scope: [hi]

[2] PowerShell 中 $private: 范围的演示

# & { ... } executes ... in a child scope.
# Referencing a variable by itself implicitly outputs it (implicit `echo `).
PS> $var = 'outer'; & { $private:var = 'inner'; $var; & { $var } }
inner
outer

也就是说,私有 $var 仅在外部 { ... } 内部直接可见;嵌套的 { ... } 再次看到了 grandparent 作用域的 $var.