1.=>
在了解Scala的By-Name参数之前,先了解下“=>”在Scala中有几种用法:
1.对于值,“=>”相当于lambda表达式。如:scala> List(1,2,3).map{(x: Int) => x*2}
res0: List[Int] = List(2, 4, 6)
2.对于类型,“=>”两端的类型(如,A => B、(A, B) => C等)。它对于Function<n>[A[, B...], T]是一个语法糖。一个函数传入参数是A[, B...],并且返回一个T类型的值。如:
scala> val test: Function1[Int,String] = myInt => "my int: " + myInt.toString
test: Int => String = <function1>
scala> test(1)
res0: String = my int: 1
scala> val test: Int => String = myInt => "my int: "+ myInt.toString
test: Int => String = <function1>
scala> test(1)
res1: String = my int: 1
- 如果参数为空,即“=>”左边为空,形式是:() => T。如
scala> val test: Function0[String] = () => "Hello" test: () => String = <function0> scala> test() res3: String = Hello scala> val test: () => String = () => "Hello" test: () => String = <function0> scala> test() res4: String = Hello
如果无返回值,即“=>”右边为空,形式是:A[, B...] => Unitscala> val test: Int => Unit = myInt => println(myInt) test: Int => Unit = <function1> scala> test(1) 1
如果无参且无返回值,即“=>”两边都为空,形式是:() => Unitscala> val test: Function0[Unit] = () => println("Hello") test: () => Unit = <function0> scala> test() Hello scala> val test: () => Unit = () => println("Hello") test: () => Unit = <function0> scala> test() Hello
4.在case语句中,“=>”用于分隔模式和结果表达式。
2.By-Name Parameter
By-Value参数,我们都比较熟悉,参数在进入函数前就进行计算,最后传入的最终的计算结果。By-Name参数,表示参数在进入函数后,每次在函数体内调用的时候才会计算。
def myByName1(param: () => Boolean): Unit = {
println("start")
println(param) //println(param.apply())也可以
println("end")
}
//要实现传名函数,要定义的类型开始于“=>”,而不是“() =>”。
//myByName1{7>9}不会有效,因为缺少“() =>”
myByName1{() =>
println("enter")
7 > 9
}
其中“=>”后面的代码是整体作为参数,所以会在函数体里被调用的时候才会执行。输出如下:
start
enter
false
end
再看下一种情况,只有“() =>”之后的代码是By-Name参数。“() =>”之前的代码是By-Value参数,即当调用myByName2的时候就会立即执行:
def myByName2(param: () => Boolean): Unit = {
println("start")
println(param) //println(param.apply())也可以
println("end")
}
myByName2{
println("enter")
() => 7 > 9
}
输出如下:
enter
start
false
end
下面来看标准的By-Name参数:
def myByName(param: => Boolean): Unit = {
println("start")
println(param)
println("end")
}
myByName{
println("enter")
7 > 9}
3.函数作为参数
By-Name有点像把函数作为参数的意思,但是实际上却不是。这里看下把函数作为参数的形式:
def test(num: Int => String, str: String => Int): Unit = {
val i = 10
val s = "5"
println(num(i))
println(str(s))
}
def num(x: Int): String = {
x.toString()
}
def str(s: String): Int = {
s.toInt
}
test(num, str)
参考文献: