как передать массив в функцию и обновления массива отражаются вне функции

Я пытаюсь передать массив в функцию, и любые изменения, внесенные в массив, отражаются за пределами функции.

function update_array()
{   
    ${1[0]}="abc" # trying to change zero-index array to "abc" , 
                  #  bad substitution error


}

foo=(foo bar)

update_array foo[@]

for i in ${foo[@]}
    do
       echo "$i" # currently changes are not reflected outside the function

    done

Мои вопросы:

1) Как получить доступ к индексный массив, например: нулевой индексный массив, в функции, каков синтаксис для него

2) Как я могу внести изменения в этот индексный массив, чтобы изменения отражались и вне функции

2
задан 10 January 2014 в 09:17

3 ответа

Несколько проблем, в логическом порядке фиксации:

  • Разработайте (главный объект неприязни)
  • С Вашим ${...} оператор в update_array(), ${..} синтаксис для использования переменной, не определяют его.

    Пример:

    foo[0]=abc  # assigns 'abc' to foo[0]
    
  • При работе вокруг этого имя массива хранится в переменной.

    Не работа:

    $1[0]=abc
    

    Работа:

    declare -g "$1[0]=abc"  # -g arg is for a global variable
    
  • Передача аргумента update_array() должен передать имя переменной (foo в этом случае), не содержание массива. foo[@] ничего специального, это - абсолютно нормальная строка (в Bash).

  • Переменное расширение с ${foo[@]} должен быть дважды заключен в кавычки.

Рабочая версия кода ниже:

update_array() {   
    declare -g "$1[0]=abc"
}

foo=(foo bar)

update_array foo

for i in "${foo[@]}"; do
    echo "$i"
done

## Following line added by me for further clarification
declare -p foo

который печатает, правильно:

abc
bar
declare -a foo='([0]="abc" [1]="bar")'
3
ответ дан 10 January 2014 в 09:17

Объявление переменных в Bash может не потребоваться. 1 Да, вы можете использовать declare / typeset для большего контроля над вашим bash. переменные. Поэтому я считаю, что вам не нужно создавать функцию только для объявления нового массива.

Этот скрипт ниже демонстрирует прямое определение массива:

#!/bin/bash
function define_array_elements() {
# You can note the array elements being defined directly, without a prior 
# definition of the variable.
for i in {1..10}; do
    var_name[$i]="Field $i of the list"
done
}

define_array_elements > /dev/null

for i in {1..10}; do
    echo "Field $i is: ${var_name[$i]}"
done

(Пример заимствован из Как объявить массив, но не определить его? с небольшой модификацией.)

0
ответ дан 10 January 2014 в 09:17

Краткий ответ: вы не можете. Bash не имеет способа передачи переменных по ссылке, поэтому нет общего способа сделать это; у вас остались (некрасивые) хаки, в том числе косвенные и / или eval.

В следующем выпуске bash 4.3 появятся переменные nameref, которые позволят вам передавать переменные по ссылке, но даже эта функция не дотягивает, так как вы все еще рискуете столкнуться с именем.

# example of passing variables by reference in bash 4.3
update_array() {
    declare -n array=$1
    array[0]=abc
}

foo=( foo bar )

update_array foo

printf '<%s>\n' "${foo[@]}" # outputs <abc> and <bar>

В этом примере, если массив был назван array вместо foo, он потерпит неудачу, поскольку declare -n array=array является ошибкой (declare: array: nameref variable self references not allowed).

См. http://mywiki.wooledge.org/BashFAQ/006 для других хаков.

0
ответ дан 10 January 2014 в 09:17
  • 1
    Что Вы имеете в виду? Это повредилось, прежде чем я даже начал бездельничать с драйверами Nvidia (они были удалены теперь), – user3302053 1 July 2015 в 02:20

Другие вопросы по тегам:

Похожие вопросы: