parameters可以认为是与形参(formal parameter)对应,在函数定义时,用来表示如何处理将来传进来的数据,它需要类型信息。arguments是实参(acturla parameter),当函数调用时,表示传递进去的数据。它的类型必须与函数定义时的parameters相同,否则就是类型不匹配的错误。
例如:def f(x): x*x 这里的x就是parameter,而在定义之后,调用时,a = 2;f(a),那么a就是argument。
parameters可以看作函数的固定属性,它们表征了函数内部的特性,例如如何操作传递进来的参数,实际上起着占位符的作用;arguments是随着函数调用的上下文而变,在代码运行时,占位符将被实际参数的值取代。
这就有一个问题:如何以及何时计算argument的值?
在call by value 和call by reference方案里,函数应用都是在进入函数体之前求arguments的值。因此,函数必须能够查询当前arguments的值,并通过赋值语句改变它们的值。
call by value就是在执行函数前,计算argument的值,并且把计算结果绑定到函数内的参数上,通常是在内存中重新分配空间。当函数返回后,这个空间也被收回,也就是说在上例中,a = 2; f(a); 如果在函数内部发生对a的赋值,调用函数f(a)返后,a的值是不变的,还是2。
call by refernce策略有所不同,在argument值的计算过程中,传递进来的不再是值,而是对它们的直接引用,也既是,如果对参数重新赋值,函数调用返回后,在caller的作用域是能看到值的变化。
def modify(var p, &q) {
p := 27 # passed by value - only the local parameter is modified
q := 27 # passed by reference - variable used in call is modified
}
? var a := 1
# value: 1
? var b := 2
# value: 2
? modify(a, &b)
? a
# value: 1
? b
# value: 27