简介
传值参数(by-value parameter) 在函数调用之前表达式会被求值,例如Int
,Long
等数值参数类型;传名参数(by-name parameter) 在函数调用前表达式不会被求值,而是作为一个匿名函数传递。在介绍两者区别之前,先说一下 => 的用法。
=> 用法
=> 用法主要有以下几点:
对于值,相当于lambda表达式:
1
2scala> List(1, 2, 3).map{(x: Int) => x * 2}
res0: List[Int] = List(2, 4, 6)对于类型,=> 用于分开两端的类型。
1
2
3
4
5
6
7
8
9
10
11scala> val test: Function1[Int, String] = myInt => "myInt: " + myInt.toString
test: Int => String = <function1>
scala> test(10)
res0: String = myInt: 10
scala> val test: Int => String = myInt => "myInt: " + myInt.toString
test: Int => String = <function1>
scala> test(10)
res1: String = myInt: 10如果参数为空,即 => 左边为空,形式为 ()=>T:
1
2
3
4
5
6
7
8
9
10
11scala> val test: Function0[String] = () => "Hello world"
test: () => String = <function0>
scala> test()
res11: String = Hello world
scala> val test: () => String = () => "Hello world"
test: () => String = <function0>
scala> test()
res12: String = Hello world如果无返回值,即形式为 A[,B,…]=>Unit:
1
2
3
4
5
6
7
8
9
10
11scala> val test: Function1[Int, Unit] =myInt => println(myInt)
test: Int => Unit = <function1>
scala> test(10)
10
scala> val test: Int => Unit =myInt => println(myInt)
test: Int => Unit = <function1>
scala> test(10)
10如果无参数无返回值,即形式为 []=>Unit:
1
2
3
4
5
6
7
8
9
10
11scala> val test: Function0[Unit] = () => println("Hello world")
test: () => Unit = <function0>
scala> test()
Hello world
scala> val test: () => Unit = () => println("Hello world")
test: () => Unit = <function0>
scala> test()
Hello world如果作为一个函数的参数的类型声明,且坐便没有符号,如
def func(param: => T)
。这种形式叫做传名参数;- 在case语句中,=> 用于分隔模式和结果表达式。
传值参数
先对表达式进行计算,然后将结果带入函数。
- 简单类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 object Demo01 {
def strToInt(s: String) = {
println("call strToInt")
s.toInt
}
def main(args: Array[String]): Unit = {
strToInt({
println("call by value"); "10"
})
}
}
//output:
//call by value
//call strToInt
- 复杂类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20object Demo02 {
def func(f: String => Int => Long): Long = {
println("call func")
f("1")(2)
}
def curry(s: String)(i: Int): Long = {
s.toLong + i.toLong
}
def main(args: Array[String]): Unit = {
func {
println("call by value")
curry
}
}
}
//output:
//call by value
//call func
传名参数
参数在进入函数后,每次在函数体内调用的时候才会计算。
- 简单类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 object Demo01 {
def strIoInt(s: => String): Int = {
println("call strToInt")
s.toInt
}
def main(args: Array[String]): Unit = {
strIoInt({
println("call by name")
"10"
}
)
}
}
// output:
// call strToInt
// call by name
- 复杂类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20object Demo02 {
def func(f: => String => Int => Long): Long = {
println("call func")
f("1")(2)
}
def curry(s: String)(i: Int): Long = {
s.toLong + i.toLong
}
def main(args: Array[String]): Unit = {
func {
println("call by name")
curry
}
}
}
// output:
// call func
// call by name
总结
() => T 可以简写成 => T。
- 示例-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 object Demo03 {
def strIoInt(s: () => String): Int = {
println("call strToInt")
s().toInt
}
def main(args: Array[String]): Unit = {
// 注意调用的顺序
strIoInt({
println("call by value")
() => {
println("call by name"); "10"
}
}
)
}
}
// output:
// call by value
// call strToInt
// call by name
- 示例-2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26object Demo04 {
def func(f: () => String => Int => Long): Long = {
println("call func")
f()("1")(2)
}
def curry(s: String)(i: Int): Long = {
s.toLong + i.toLong
}
def main(args: Array[String]): Unit = {
// 注意调用的顺序
func({
println("call by value")
() => {
println("call by name")
curry
}
}
)
}
}
// output:
// call by value
// call func
// call by name