【问题标题】:How to use a bash variable reference to an associative array in a bash function without declaring it before calling that function?如何在 bash 函数中使用对关联数组的 ba​​sh 变量引用而不在调用该函数之前声明它?
【发布时间】:2021-09-10 23:37:42
【问题描述】:

有多种方法可以从 bash 脚本中的函数获取结果,一种是使用引用变量,如 local -n out_ref="$1,这也是我的首选方式。

我的 bash 版本是:

GNU bash, Version 5.0.3(1)-release 

最近,我的一个 bash 函数需要生成一个关联数组,就像在这个示例代码中一样:

#!/bin/bash

testFunction() {
    local -n out_ref="$1"

    out_ref[name]="Fry"
    out_ref[company]="Planet Express"
}

declare -A employee
testFunction employee

echo -e "employee[name]: ${employee[name]}"
echo -e "employee[company]: ${employee[company]}"

我将变量employee 声明为与declare -A 的关联数组。

输出是:

employee[name]: Fry
employee[company]: Planet Express

如果我删除行declare -A employee,输出是:

employee[name]: Planet Express
employee[company]: Planet Express

有没有办法将关联数组的声明移到函数中,这样函数的用户就不需要事先做?

【问题讨论】:

  • 使用declare -p employee 而不是echo 来检查变量及其属性。

标签: arrays bash pass-by-reference associative-array


【解决方案1】:

在函数内部使用declare -Ag "$1",这样你就可以将employee声明为一个全局变量。

【讨论】:

  • 如果我在函数内部执行declare -Ag "$1",我该如何使用该变量,例如我的示例中的out_ref[name]="Fry"
【解决方案2】:

如果没有declare -A employeeemployee 基本上被视为普通的索引数组。在这种情况下,nameemployee 都是在算术上下文中求值的未定义变量,因此都求值为 0。

我不完全确定 local -n 是如何实现的(local -nA 不允许将引用标记为关联数组),但似乎缺少要分配的“真实”关联数组,值employee 就是分配给引用 out_refany 键的最后一个值。 (可能与上面相同:namecompany 在算术上下文中都计算为 0,因此您分配给 out_ref[0] 两次(并且因为 out_ref 不引用数组标记的名称,所以您是只是分配给out_ref 本身。)

【讨论】:

    【解决方案3】:

    扩展这些更好的头脑所提供的内容,这是一个在实际使用中展示它的功能示例。

    A() {
      declare -Ag "$1"
      local -n ref="$1"
      ref[A]='in A'
    }
    
    B() {
      declare -Ag "$1"
      local -n ref="$1"
      ref[B]='in B'
    }
    
    A foo
    B foo
    declare -p foo
    

    保存并执行为名为@9​​87654322@ 的文件,这是运行和输出 -

    $: ./tst
    declare -A foo=([A]="in A" [B]="in B" )
    

    请注意,在多个函数中“重新声明”全局变量并不影响数据完整性。

    【讨论】:

    • 感谢您提供这些示例!
    • 我想知道它是如何工作的,如果我想从另一个应该产生关联数组结果的函数 B 调用函数 A。也许这是不可能的,因为您无法通过 local -n 声明本地关联数组引用。
    • 上面的A&B函数都声明local -n ref="$1",每一个用来引用传递的名字都是一个关联数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多