代码之家  ›  专栏  ›  技术社区  ›  Antoine Morrier

给函数一个数组,感叹号?

  •  0
  • Antoine Morrier  · 技术社区  · 7 年前

    我正试图给一个函数赋一个数组。我成功地完成了这个解决方案:

    test_arr() {
      local a="${!1}"
      for i in ${a[@]}
      do
        echo $i
        printf '\n'
      done
    }
    
    arr=("lol 1" "lol 2" "lol 3");
    test_arr arr[@]
    

    但是有两个问题:通过 local 变量。所以我可以用 $1 直接在for循环中,我不理解 ${!1} . 什么意思 ! ?

    另一个问题是,对于我的shell,有6个元素而不是3个

    1 回复  |  直到 7 年前
        1
  •  1
  •   Ondrej K.    7 年前

    如果只想将数组的值传递给函数,可以这样做:

    test_arr() {
      for i in "$@"; do
        echo $i
        printf '\n'
      done
    :
    }
    
    arr=("lol 1" "lol 2" "lol 3")
    test_arr "${arr[@]}"
    

    "${arr[@]}" 将正确分隔的所有值传递给我们可以通过其访问的函数 $@ (所有参数)。

    ! 你问过的是用来间接参考的。即。 "${!1}" 不是第一个参数的值,而是名称与第一个参数的值相同的变量的值。


    我可能错过了一些东西,但似乎想同时结合间接引用数组的所有项和访问间接引用数组的所有项会对shell要求太多,所以我召唤出强大的 eval (很好的理由开始保持谨慎)来帮助我们。我已经破解了这个方法,它允许您将数组名传递给一个函数,然后根据函数的第一个参数中看到的那个名称访问它的项,但是它并不漂亮,仅此一项就足以让您气馁而不这样做。它确实创建了一个局部变量/数组作为您的示例,假设有一些原因需要这样做。

    test_arr() {
      local a
      eval a=(\"\$\{$1\[@\]\}\")
      for i in "${a[@]}"; do
              echo $i
      done
    }
    
    arr=("lol 1" "lol 2" "lol 3")
    test_arr arr