Как передать аргумент массива в функцию - PullRequest
0 голосов
/ 05 ноября 2018

Я реализовал простую функцию сортировки слиянием в PowerShell, вот так

function Merge-Sort
{
  param($a)
  if ($a.Length -gt 1)
  {
    $m = [Math]::floor($a.Length / 2)
    [Int[]]$l = $a[0..($m-1)]
    [Int[]]$r = $a[$m..($a.Length)]

    Merge-Sort $l
    Merge-Sort $r

    $i = $j = $k = 0

    while ($i -lt $l.Length -and $j -lt $r.Length)
    {
      if ($l[$i] -lt $r[$j])
      {
        $a[$k] = $l[$i]
        $i++
      }
      else
      {
        $a[$k] = $r[$j]
        $j++
      }
      $k++
    }

    while($i -lt $l.length)
    {
        $a[$k] = $l[$i]
        $i++
        $k++
    }

    while($j -lt $r.length)
    {
        $a[$k] = $r[$j]
        $j++
        $k++
    }
 }
}

Функции делают то, что должны, и сортируют массив целочисленных значений:

 $arr = @(22,44,55,11,66,11,77,99,33,88)
 merge-sort $arr

Вывод: 11 11 22 33 44 55 66 77 88 99

Но когда я определяю параметр функции как [Int []], чтобы прояснить, что это должен быть массив целых чисел, вместо объекта что-то пошло не так, и массив остается несортированным:

 function Merge-Sort
 {
    param([Int[]]$a)
    ...
 }

Выход: 22 44 55 11 66 11 77 99 33 88

Мой вопрос:

Почему правильный способ определения параметра функции приводит к неверному результату (массив не сортируется)?

1 Ответ

0 голосов
/ 05 ноября 2018

Когда создается объект $ arr, поскольку он не был определен как массив int [int []], он был создан как [массив]. При передаче в функцию первоначально до добавления [int []]. Он передал ссылку и изменил данные. Если бы вы добавили объект дополнения к массиву, он бы ничего не возвратил, так как это создало бы новый объект массива.

Когда вы добавили [int []] к параметру, он создал новый объект int array [int []] с именем $ a и изменил там данные. Поскольку $ a никогда не возвращается, переменная уничтожается в конце функции.

Если бы вы передали массив int, он бы манипулировал этим массивом.

Давайте рассмотрим несколько примеров

Это изменит первое значение с индексом 0 на 5. Поскольку ни один объект не был добавлен в массив, а массив может быть любым объектом в параметре, он позволил изменить ссылку на индекс 0 вместо того, чтобы нуждался в новом объекте. подлежит возврату

function TestFunction($a)
{
    $a[0] = 5
}
$TestVar = @(2,3,1)
TestFunction -a $TestVar
$TestVar

output 5,3,1

Поскольку объект orignal имеет тип Array, а параметр имеет тип int array. функция создаст новый массив int на основе входного массива. Так как функция должна возвращать новый массив int и возврата нет, сборщик мусора будет.

function TestFunction([int[]]$a)
{
    $a[0] = 4
}
$TestVar = @(2,3,1)
TestFunction -a $TestVar
$TestVar

Так что в вашем случае мы можем сделать

function TestFunction([int[]]$a)
{
  $a[0] = 4
}
[int[]]$TestVar = @(2,3,1)
TestFunction -a $TestVar
$TestVar

поскольку параметр ищет массив int, а входные данные являются массивом int, а новые объекты не добавляются и не вычитаются из массива, это приведет к правильному изменению значения.

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