awk作用域问题

awk只有在函数参数中才是局部变量,其它地方定义的变量均为全局变量。

函数内部新增的变量是全局变量,会影响到全局,所以在函数退出后仍然能访问。例如上面的e变量。

  1. awk '
    function f(){
    a=30 # 新增的变量,是全局变量
    print "in f: " a
    }
    BEGIN{
    a=40
    f()
    print a # 30
    }
    '

函数参数会遮掩全局同名变量,所以在函数执行时,无法访问到或操作与参数同名的全局变量,函数退出时会自动撤掉遮掩,这时才能访问全局变量。所以,参数具有局部效果。

  1. awk '
    function f(a){
    print a # 50,按值拷贝,和全局a已经没有关系
    a=40
    print a # 40
    }
    BEGIN{
    a=50
    f(a)
    print a # 50,函数退出,重新访问全局变量
    }
    '

由于函数内部新增变量均为全局变量,awk也没有提供关键字来修饰一个变量使其成为局部变量。所以,awk只能将本该出现在函数体内的局部变量放在参数列表中,只要调用函数时不要为这些参数传递数据即可,从而实现局部变量的效果。

  1. awk '
    function f(a,b ,c,d){

    # a,b是参数,调用时需传递两个参数
    # c,d是局部变量,调用时不要给c和d传递数据
    a=30
    b=40
    c=50
    d=60
    e=70 # 全局变量

    print a,b,c,d,e # 30 40 50 60 70
    }
    BEGIN{
    a=31
    b=41
    c=51
    d=61
    f(a,b) # 调用函数时值传递两个参数
    print a,b,c,d,e # 31 41 51 61 70
    }
    '

所以,awk对函数参数列表做了两类区分:

  • arguments:调用函数时传递的参数
  • local variables:调用函数时省略的参数

为了区分arguments和local variables,约定俗成的,将local variables放在一大堆空格后面来提示用户。例如function name(a,b, c,d)表示调用函数时,应当传递两个参数,c和d是本函数内部使用的局部变量,不要传递对应的参数。

区分参数和局部变量:

  • 参数提供了函数和它调用者进行数据交互的方式
  • 局部变量是临时存放数据的地方

arguments部分体现的是函数调用时传递的参数,这些参数在函数内部会遮掩全局同名变量。例如上面示例中,函数内部访问不了全局的a和b,所有对a和b的操作都是函数内部的,函数退出后才能重新访问全局a和b。因此,arguments也有局部特性。

local variables是awk实现真正局部变量的技巧,只是因为函数内部新增的变量都是全局变量,所以退而求其次将其放在参数列表上来实现局部变量。

打赏作者

23. awk自定义函数(2):awk作用域 - 图1