回到:


awk作用域问题

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

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

1
2
3
4
5
6
7
8
9
10
11
awk '
function f(){
a=30 # 新增的变量,是全局变量
print "in f: " a
}
BEGIN{
a=40
f()
print a # 30
}
'

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

1
2
3
4
5
6
7
8
9
10
11
12
awk '
function f(a){
print a # 50,按值拷贝,和全局a已经没有关系
a=40
print a # 40
}
BEGIN{
a=50
f(a)
print a # 50,函数退出,重新访问全局变量
}
'

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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实现真正局部变量的技巧,只是因为函数内部新增的变量都是全局变量,所以退而求其次将其放在参数列表上来实现局部变量。