Lambda 表达式
Lambda 表达式定义
Lambda 表达式的语法为如下形式: { p1: T1, ..., pn: Tn => expressions | declarations }
。
其中,=>
之前为参数列表,多个参数之间使用 ,
分隔,每个参数名和参数类型之间使用 :
分隔。=>
之前也可以没有参数。=>
之后为 lambda 表达式体,是一组表达式或声明序列。Lambda 表达式的参数名的作用域与函数的相同,为 lambda 表达式的函数体部分,其作用域级别可视为与 lambda 表达式的函数体内定义的变量等同。
let f1 = { a: Int64, b: Int64 => a + b }
var display = { => println("Hello") } // Parameterless lambda expression.
Lambda 表达式不管有没有参数,都不可以省略 =>
,除非其作为尾随 lambda。例如:
var display = { => println("Hello") }
func f2(lam: () -> Unit) { }
let f2Res = f2{ println("World") } // OK to omit the =>
Lambda 表达式中参数的类型标注可缺省。以下情形中,若参数类型省略,编译器会尝试进行类型推断,当编译器无法推断出类型时会编译报错:
- Lambda 表达式赋值给变量时,其参数类型根据变量类型推断;
- Lambda 表达式作为函数调用表达式的实参使用时,其参数类型根据函数的形参类型推断。
// The parameter types are inferred from the type of the variable sum1
var sum1: (Int64, Int64) -> Int64 = { a, b => a + b }
var sum2: (Int64, Int64) -> Int64 = { a: Int64, b => a + b }
func f(a1: (Int64) -> Int64): Int64 {
a1(1)
}
main(): Int64 {
// The parameter type of lambda is inferred from the type of function f
f({ a2 => a2 + 10 })
}
Lambda 表达式中不支持声明返回类型,其返回类型总是从上下文中推断出来,若无法推断则报错。
-
若上下文明确指定了 lambda 表达式的返回类型,则其返回类型为上下文指定的类型。
-
Lambda 表达式赋值给变量时,其返回类型根据变量类型推断返回类型:
let f: () -> Unit = { ... }
-
Lambda 表达式作为参数使用时,其返回类型根据使用处所在的函数调用的形参类型推断:
func f(a1: (Int64) -> Int64): Int64 { a1(1) } main(): Int64 { f({ a2: Int64 => a2 + 10 }) }
-
Lambda 表达式作为返回值使用时,其返回类型根据使用处所在函数的返回类型推断:
func f(): (Int64) -> Int64 { { a: Int64 => a } }
-
-
若上下文中类型未明确,与推导函数的返回值类型类似,编译器会根据 lambda 表达式体中所有 return 表达式
return xxx
中 xxx 的类型,以及 lambda 表达式体的类型,来共同推导出 lambda 表达式的返回类型。-
=>
右侧的内容与普通函数体的规则一样,返回类型为Int64
:let sum1 = { a: Int64, b: Int64 => a + b }
-
=>
的右侧为空,返回类型为Unit
:let f = { => }
-
Lambda 表达式调用
Lambda 表达式支持立即调用,例如:
let r1 = { a: Int64, b: Int64 => a + b }(1, 2) // r1 = 3
let r2 = { => 123 }() // r2 = 123
Lambda 表达式也可以赋值给一个变量,使用变量名进行调用,例如:
func f() {
var g = { x: Int64 => println("x = ${x}") }
g(2)
}