Почему Range.BorderAround излучает «True» на консоль? - PullRequest
1 голос
/ 13 апреля 2019

При использовании BorderAround выдает «True» на консоль.

$range = $sum_wksht.Range('B{0}:G{0}' -f ($crow))
$range.BorderAround(1, -4138)

Эту проблему можно решить одним из следующих способов.

$wasted = $range.BorderAround(1, -4138)
[void]$range.BorderAround(1, -4138)

Зачем это нужно?Я правильно не создаю диапазон?Есть ли лучший обходной путь?

1 Ответ

1 голос
/ 13 апреля 2019

Зачем это нужно?

Это необходимо, поскольку метод BorderAround имеет возвращаемое значение, а в PowerShell любая командаили выражение ..., которое выводит (возвращает) данные , равное , неявно выводит в свой (успешный) выходной поток , которыйпо умолчанию идет на хост , который обычно является консольным окном (терминал), в котором выполняется сеанс PowerShell.

То есть данные отображаются в консоли/ терминал, , если это:

  • захвачено ($var = ...)
  • отправлено по конвейеру для дальнейшей обработки (... | ...; последний сегмент конвейеракоманда может выдавать или не выводить сама)
  • перенаправлено (... >)

или любая их комбинация.

То есть:

$range.BorderAround(1, -4138)

является (более эффективным) сокращением для:

Write-Output $range.BorderAround(1, -4138)

(Явное использование Write-Output редко требуется.)

Поскольку вы надеваетене хочуна выходе вы должны подавить это , для которого у вас есть несколько вариантов:

  • $null = ...

  • [void] (...)

  • ... > $null

  • ... | Out-Null

$null = ... может быть лучшим общим выбором , потому что:

  • передает намерение подавить вперед
    • [void] = (...) делает это тоже,но часто требует, чтобы вы приложили остальную часть утверждения в (...) по синтаксическим причинам;например, [void] 1 + 2 не работает должным образом, только [void] (1 + 2)
  • он хорошо работает как с выходными данными command (например, $null = Get-AdUser ...), так и выражение вывод (например, $null = $range.BorderAround(1, -4138)).

И наоборот, избегать ... | Out-Null, потому что обычно он намного медленнее (за исключением вывода выражения в PowerShell) Core ).

Однако, , если вам нужно отключить все выходных потоков - не только успех вывод, но также и ошибки, подробный вывод, ... - вы должны использовать *> $null


Почему PowerShell производит вывод неявно?

  • Как shell , Выходное поведение PowerShell основано на потоков , как в традиционных оболочках, таких как cmd.exe или Bash.(Хотя традиционные оболочки имеют 2 выходных потоков - stdout и stderr - PowerShell имеет 6 , чтобы обеспечить более сложные функциональные возможности - см. about_Redirection .)

    • Командлет, сценарий или функция могут записывать в выходные потоки столько раз, сколько пожелают, и такой вывод обычно мгновенно доступен для отображения, но особенно дляпотенциальные потребители , что обеспечивает потоковую обработку по одному, которую конвейер обеспечивает .

    • Это отличается от традиционного языки программирования , выходное поведение которых основано на возвращаемых значениях , обычно предоставляемых через ключевое слово return, которое связывает выходные данные (возвращаемое значение) с управлением потоком (выход из области действия ивернитесь к вызывающей стороне).

      • Часто ловушкой можно ожидать, что оператор PowerShell return будет действовать так же, но это не так: return <val> является просто синтаксическим сахаром для <val>; return, т.е.,неявный вывод <val> с последующим безусловным возвратом управления вызывающей стороне;в частности, использование return делает не исключающим генерацию вывода из более ранних операторов в той же области.
  • В отличие отдля традиционных оболочек PowerShell не требует явной команды потока записи для вывода для получения вывода :

    • ХотяPowerShell имеет аналог echo, а именно Write-Output, его использование редко требуется.

      • Среди редких случаев, когда полезно Write-Output, можно предотвратить перечисление коллекции при выводе с -NoEnumerate или использовать общий параметр -OutVariable для обоих выходных данных и записать его в переменную (которая обычно требуется только для выражений , поскольку сами командлеты и расширенные функции / сценарии поддерживают -OutVariable).
    • неявное поведение вывода :

      • обычно является благословением :

        • дляинтерактивное экспериментирование - просто введите любое утверждение - особенно включая выражения, такие как [IO.Path]::GetExtension('foo.txt') и [math]::Pow(2, 32) - и посмотрите его вывод (сродни поведению REPL ).
        • для краткой записикод, который не должен разъяснять подразумеваемое поведение (см. пример ниже).
      • может иногда быть ловушкой :

        • для пользователей, привыкших к семантике традиционных языков программирования.

        • из-за возможного случайного загрязнения выходного потока из-за заявлений, которые вы не ожидаете получить, например, в вашем случае;более типичным примером является метод .Add() класса [System.Collections.ArrayList], неожиданно производящий вывод.

Пример:

# Define a function that takes an array of integers and
# outputs their hex representation (e.g., '0xa' for decimal 10)
function Get-HexNumber {
  param([int[]] $numbers)      
  foreach ($i in $numbers) {
    # Format the integer at hand 
    # *and implicitly output it*.
    '0x{0}' -f $i.ToString('x')
  }
}

# Call the function with integers 0 to 16 and loop over the
# results, sleeping 1 second between numbers.
Get-HexNumber (0..16) | ForEach-Object { "[$_]"; Start-Sleep 1 }

Выше приведено следующее:

[0x0]
# 1-second pause
[0x1]
# 1-second pause
[0x2]
...
[0x10]

Это демонстрирует аспект потоковой передачи поведения: вывод Get-HexNumber доступен для вызова командлета ForEach-Object в процессе производства , а не после выхода Get-HexNumber.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...