scala 拥有两种参数传递的方式:按值传递 与 按名传递。按值传递 避免了参数的重复求值,效率相对较高;而 按名传递 避免了在函数调用时刻的参数求值,而将求值推延至实际调用点,但有可能造成重复的表达式求值。
值传递:先计算参数表达式的值,再应用到函数内部;
def main(args: Array[String]): Unit = {
def f: () => Int = () => {
println("f...")
10
}
foo(f())
}
def foo(a: Int) = {
println(a)
println(a)
println(a)
}
运行结果:
f...
10
10
10
说明: 调用 foo(f()) 方法时,会首先调用并执行 函数 f 中的代码,并将最后的返回值: 10 传递给 foo(a: Int) 方法 ,所以 f... 执行一次, 10 执行 三次
名传递:将未计算的参数表达式直接应用到函数内部
def main(args: Array[String]): Unit = {
def f: () => Int = () => {
println("f...")
10
}
foo(f())
}
def foo(a: => Int) = {
println(a)
println(a)
println(a)
}
运行结果:
f...
10
f...
10
f...
10
说明: foo(a: => Int) 方法中增加了 => 表示 名传递,调用 foo(a: => Int) 方法时, 会将 函数 f 整个传递给 foo(a: => Int) 方法,在 该方法中,每次 println(a) 都会执行被完整传递过来的 函数 ,所以 println 一下 打印一次 f... 和 10
在上述名传递例子中, 调用 foo 方法时需要传入另一个 函数,所以我们需要额外定义一个具名函数,而名传递的本质是:传递函数本身,所以这个步骤下面精简一下
def main(args: Array[String]): Unit = {
// def f: () => Int = () => {
// println("f...")
// 10
// }
// foo(f2())
// 第一次精简
// 这里直接传递一个匿名函数
// foo(() => {
// println("匿名函数...")
// 10
// })
// 第二次精简
//foo的调用还可以将匿名函数的部分省略成
// foo({
// println("匿名函数...")
// 10
// })
//第三次精简
// 还可以省略
foo{
println("匿名函数...")
10
}
}
def foo(a: => Int) = {
println(a)
println(a)
println(a)
}
运行结果:
匿名函数...
10
匿名函数...
10
匿名函数...
10
抽象控制
def main(args: Array[String]): Unit = {
var i = 1;
myWhile(i <= 100){
println(i)
i += 1
}
}
def myWhile(flag: => Boolean)(exp: => Unit): Unit = {
if(flag) {
exp
myWhile(flag)(exp)
} else
println("循环结束....")
}
本文深入探讨Scala中的参数传递方式,包括按值传递和按名传递的区别及应用场景。通过实例演示了参数传递对函数调用的影响,以及如何利用名传递简化代码。
59

被折叠的 条评论
为什么被折叠?



