Для этого вам не нужна функция в PowerShell, потому что она поставляется с операторами удержания коллекции
-contains
и -in
(они отличаются только тем, идет ли массив на LHS или RHS):
# 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
), как и ожидалось.
Предостережение : PowerShell, в отличие от традиционных оболочек, имеет систему расширенного типа на основе .NET, что означает, что (подразумеваемое) сравнение на равенство может не всегда работать должным образом; короче говоря, из-за автоматического преобразования типов порядок операндов в сравнении имеет значение, так что '0xa' -in 10, 'other'
равен $true
, а 10 -in '0xa', 'other'
нет - подробности см. в нижнем разделе этого ответа .
Если вам нужно скопировать функцию 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-подобные оболочки, такие как как это делает Bash - см. нижнюю часть этого ответа для получения дополнительной информации.
Локальные переменные в PowerShell и в POSIX-подобных оболочках (например, Bash)
$e
и $arr
в функции выше являются локальными переменными, неявно так; если вы хотите сделать этот факт явным, вы можете использовать $local:e, $local:arr = $args
, но это никогда не требуется, поскольку присваивание переменной в PowerShell неявно и неизменно создает ее в локальная (текущая) область действия .
Это отличается от POSIX-подобных оболочек , где назначение без local
либо изменяет ранее существовавшую переменную в родительский область или, если таковая отсутствует, неявно создает переменную в верхнем уровне (сценарий) области действия [1]
Как и в POSIX-подобных оболочках, потомки областей в PowerShell (дочерние области и их дочерние элементы ...) делают см. локальную переменную .
- В отличие от POSIX-подобных оболочек (за исключением
ksh
[1] ), PowerShell также предлагает способ создать действительно локальную переменную , т. Е. переменная, которая является видимой и изменяемой только в определяющей области, а именно через модификатор $private:
scope : $private:var = 'truly local'
[2] .
Переменная с областью действия $private
имеет эффективное поведение, которое можно ожидать от локальной переменной в лексически скомпилированном языке программирования, например C # (в отличие от динамически сценариев с областью действия языков).
В отличие от POSIX-подобных оболочек, области-потомки не могут изменять локальную переменную вызывающей стороны с помощью неквалифицированного присваивания - или любых переменных области предков, для это важно.
- Однако PowerShell предлагает явный доступ к наследственным областям , а именно через спецификаторы области действия
$script:
и $scope:
, а также через -Scope
параметр командлетов Get-Variable
и Set-Variable
.
См. Нижний раздел этого ответа для получения дополнительной информации о правилах области действия PowerShell.
[1] Демонстрация определения объема в POSIX-подобных оболочках
Следующий скрипт работает в bash
, dash
и zsh
(bash
и dash
часто используются в качестве системной оболочки по умолчанию, /bin/sh
).
Чтобы скрипт выполнялся в ksh
, вам нужно заменить ключевое слово local
на typeset
и определить функции с ключевым словом function
(function a { ...
вместо a() { ...
), потому что ksh
не понимает local
и создает только локальную переменную с синтаксисом function
.
В отличие от других упомянутых POSIX-подобных оболочек, однако, ksh
затем создает действительно локальную переменную 1167 *, не видимую в дочерних областях, так же, как в области $private:
PowerShell;другими словами: локальные ksh
переменные неизменно локально-функциональные, а потомки никогда не видят их.
#!/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] Демонстрация области действия $private:
в PowerShell
# & { ... } 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
был виден только непосредственно внутри внешнего { ... }
;вложенный { ... }
снова увидел область видимости прародителя $var
.