我无法理解 gawk 函数参数的使用。通常,参数定义函数的局部变量。
但是参数可以用作函数可以使用的输入吗?
已经看到它的使用return
实际上可以通过调用返回一个值
val=myfunc()
当您仍然可以访问全局变量时,将全局值作为输入参数传递给函数有什么好处?
答案1
你的问题是基于一个错误的前提。
通常,参数定义函数的局部变量。
不会。通常,参数为传递到函数的值定义变量名称。
awk
没有能力声明局部范围的变量。但由于所有函数参数都是可选的,因此使用变量重载函数参数列表被认为是可接受的做法,这些变量除了可以在函数中本地使用之外没有其他用途。
因此,您的问题的答案是“是”:变量可用于将值传递给函数。
例如,
awk '
function factorial(n) { return n>1 ? n*factorial(n-1) : 1 }
BEGIN { print factorial(5) }
'
此处,该函数每次使用不同的值调用自身(前 5 个,然后递减值 4、3、2)。尝试为此使用全局变量将非常困难。
答案2
另请注意,函数的标量参数是按值传递的,但数组参数是按引用传递的。因此,该函数可以将调用代码中声明的数组值更改为该函数,从而返回多个值。
这包括在数组参数中创建新元素的能力,即使它最初是作为空数组传入的。
假设我想要一个接受两个数字的函数,并且想要输出两个变量值,一个包含总和,另一个包含平均值。一个人能做什么呢?
人们可以做到这一点:它证明了同名数组存在全局和局部作用域,它们可以具有不同的长度并包含不同的数据,并且数组是通过引用传递的并且可以返回多个值。
#! /bin/bash
Awk='
#.. Define and fill an array X at global scope.
BEGIN { X[1] = 45; X[2] = 98; }
#.. Function that fills in a result array (passed by reference).
function Math (X, v1, v2) {
X[1] = v1 + v2; X[2] = (v1 + v2) / 2; X[3] = v1 * v2;
}
#.. Function that declares an array X at local scope, and reports it.
function Wrapper (a, b, X, j) {
Math( X, a, b);
for (j = 1; j in X; ++j) printf ("Local X[%d] is %f\n", j, X[j]);
}
{
Wrapper( $1, $2);
#.. Prove that the Global X is unaffected, in length or content.
for (j = 1; j in X; ++j) printf ("Global X[%d] is %f\n", j, X[j]);
}
'
echo 3.5 2.7 | awk "${Awk}"
$ ./Heime.awk
Local X[1] is 6.200000
Local X[2] is 3.100000
Local X[3] is 9.450000
Global X[1] is 45.000000
Global X[2] is 98.000000
GNU Awk 运行得很好——它在第一次访问 X 时决定 X 的类型。nawk
(Solaris Awk) 似乎在它被传入时做出了这个决定(并且可能会导致 SegViol)。
为了确保nawk
通过引用将 X 传递到函数中,您可能需要在传递之前将其显式创建为零长度数组,方法是使用零长度模式拆分零长度字符串:
split ("", X, ""); Math( X, a, b);
答案3
当您仍然可以访问全局变量时,将全局值作为输入参数传递给函数有什么好处?
与任何编程语言中的任何函数相同:您每次都可以传递不同的(全局)变量,并且该函数不需要知道完成其工作不需要的事情。
举一个简单的例子:
function sum(a,b) { return a+b; }
{ partial = sum($2, $3); }
$1 == 0 { print sum(partial, $4); }
$1 != 0 { print sum(partial, $5); }
想象一个更复杂的函数来代替sum()
,这样在两个分支中复制它就不再有意义了。