como passar array para a função e as atualizações para o array são refletidas na função outsite

2

Estou tentando passar uma matriz para uma função e quaisquer alterações feitas na matriz são refletidas fora da função

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

Minhas perguntas são

1) Como eu acesso a matriz de índice, por exemplo: matriz de índice zero, na função, qual é a sintaxe para ela

2) Como faço alterações neste array de índice para que as alterações sejam refletidas fora da função

    
por Computernerd 09.01.2014 / 18:20

3 respostas

3

Vários problemas, em ordem lógica de correção:

  • Estilo (pet peeve)
  • Com sua instrução ${...} em update_array() , a sintaxe ${..} para usar uma variável, não defini-la.

    Exemplo:

    foo[0]=abc  # assigns 'abc' to foo[0]
    
  • Trabalhando em torno de que o nome da matriz é armazenado em uma variável.

    Não funciona:

    [0]=abc
    

    Trabalhando:

    declare -g "[0]=abc"  # -g arg is for a global variable
    
  • Passar um argumento para update_array() deve passar o nome da variável ( foo neste caso), não o conteúdo da matriz. foo[@] não é nada especial, é uma string completamente normal (no Bash).

  • A expansão de variável com ${foo[@]} deve ter aspas duplas.

A versão de trabalho do código está abaixo:

update_array() {   
    declare -g "[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

que imprime corretamente:

abc
bar
declare -a foo='([0]="abc" [1]="bar")'
    
por kiri 10.01.2014 / 06:15
0

A declaração de variáveis pode não ser necessária no Bash. 1 Sim, você pode usar declare / typeset para mais controle sobre suas variáveis bash. Então, eu acho que você não precisa criar uma função apenas para declarar uma nova matriz.

Este script abaixo demonstra uma definição direta de matriz:

#!/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

(Um exemplo emprestado de Como declarar uma matriz, mas não defini-lo? com apenas uma pequena modificação.)

    
por precise 10.01.2014 / 05:50
0

Resposta curta é: você não pode. O Bash não tem como passar variáveis por referência, então não existe uma maneira genérica de fazer isso; você fica com feios (feios) incluindo indireção e / ou eval.

A próxima versão 4.3 irá introduzir as variáveis nameref, que permitem passar variáveis por referência, mas até mesmo esse recurso fica aquém, já que você ainda arrisca a colisão de nomes.

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

foo=( foo bar )

update_array foo

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

Nesse exemplo, se a matriz fosse denominada array em vez de foo , ela falharia, pois declare -n array=array é um erro ( declare: array: nameref variable self references not allowed ).

Veja link para outros hacks.

    
por geirha 10.01.2014 / 09:56