Skip to content

Latest commit

 

History

History
130 lines (111 loc) · 2.64 KB

scala值调用、名调用和控制抽象.md

File metadata and controls

130 lines (111 loc) · 2.64 KB

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("循环结束....")
}