Kotlin的语法入门-函数(let、with、also、run、apply)

对象内置函数

大括号括着代表这个函数结合了前面函数的功能。

image-20211220171249959

let函数

不为空后执行

1
2
3
4
5
6
7
8
9
10
11
12
val date = ...
data?.let{
...//如果不为空执行该语句块
}

mVar?.function1()

// 使用kotlin(使用let函数)
// 方便了统一判空的处理 & 确定了mVar变量的作用域
mVar?.let {
it.function1()
}

also函数

作用 & 应用场景

类似let函数,但区别在于返回值:

  • let函数:返回值 = 最后一行 / return的表达式
  • also函数:返回值 = 传入的对象的本身

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// let函数
var result = mVar.let {
it.function1()
it.function2()
999
}
// 最终结果 = 返回999给变量result

// also函数
var result = mVar.also {
it.function1()
it.function2()
999
}
// 最终结果 = 返回一个mVar对象给变量result

with函数

作用

调用同一个对象的多个方法 / 属性时,可以省去对象名重复,直接调用方法名 / 属性即可

应用场景

需要调用同一个对象的多个方法 / 属性

使用方法

1
2
3
4
5
 with(object){
// ...
}

// 返回值 = 函数块的最后一行 / return表达式

使用示例

1
2
3
4
5
6
7
8
9
10
11
// 此处要调用people的name 和 age属性
// kotlin
val people = People("carson", 25)
with(people) {
println("my name is $name, I am $age years old")
}

// Java
User peole = new People("carson", 25);
String var1 = "my name is " + peole.name + ", I am " + peole.age + " years old";
System.out.println(var1);

with 函数的参数可以为空,在 lambda 表达式中使用该对象的成员时就需要进行空检查。

不然,在运行时就可能会抛出 NullPointerException

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
data class Person(val name: String, val age: Int)

fun main() {
val person: Person? = null
val result = with(person) {
if (this != null) {
// 进行空检查后访问属性
"Name: $name, Age: $age"
} else {
"Person is null"
}
}
println(result)
}

run函数

作用

结合了let、with两个函数的作用,即:

  1. 调用同一个对象的多个方法 / 属性时,可以省去对象名重复,直接调用方法名 / 属性即可
  2. 定义一个变量在特定作用域内
  3. 统一做判空处理

使用方法

1
2
3
4
object.run{
// ...
}
// 返回值 = 函数块的最后一行 / return表达式

使用示例

1
2
3
4
5
6
7
8
9
10
11
// 此处要调用people的name 和 age属性,且要判空
// kotlin
val people = People("carson", 25)
people?.run{
println("my name is $name, I am $age years old")
}

// Java
User peole = new People("carson", 25);
String var1 = "my name is " + peole.name + ", I am " + peole.age + " years old";
System.out.println(var1);

apply函数

作用 & 应用场景

与run函数类似,但区别在于返回值:

  • run函数返回最后一行的值 / 表达式
  • apply函数返回传入的对象的本身

应用场景

对象实例初始化时需要对对象中的属性进行赋值 & 返回该对象

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// run函数
val people = People("carson", 25)
val result = people?.run{
println("my name is $name, I am $age years old")
999
}
// 最终结果 = 返回999给变量result

// Java
val people = People("carson", 25)
val result = people?.run{
println("my name is $name, I am $age years old")
999
}
// 最终结果 = 返回一个people对象给变量result

函数

传参写在大括号中

在 Kotlin 中,如果函数的最后一个参数是一个函数,那么可以将这个函数参数写在大括号 {} 中,这样在调用该函数时可以更清晰地表达函数的意图。

这种写法通常用于函数式编程的场景,例如定义高阶函数或使用函数字面值(lambda 表达式)。

下面是一个简单的示例,展示了如何在 Kotlin 中使用大括号 {} 来传递函数参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fun process(text: String, block: (String) -> Unit) {
println("开始处理文本:$text")
block(text)
println("处理完毕!")
}

fun main() {
val text = "Hello, Kotlin!"

// 使用大括号 {} 传递函数参数
process(text) {
println("打印文本:$it")
}
}

在上面的例子中,process 函数的最后一个参数是一个函数 (String) -> Unit,通过将这个函数写在大括号 {} 中,可以更清晰地看到这个函数是作为一个代码块传递给了 process 函数。

省略小括号

在 Kotlin 中,函数调用可以省略括号的情况有以下两种:

无参函数调用

当函数没有参数时,可以省略函数调用时的括号。

这通常用于无副作用的函数,例如 Kotlin 标准库中的一些扩展函数,比如 isEmpty()

示例如下:

1
2
3
4
val list = listOf(1, 2, 3)
if (list.isEmpty) {
println("List is empty")
}

Lambda 表达式

当函数的最后一个参数是一个 Lambda 表达式时,可以将 Lambda 表达式移到函数调用的外部,且省略函数调用时的括号。

这种语法被称为尾随闭包(Trailing Closures)。

示例如下:

1
2
val numbers = listOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 }

在上述示例中,map 函数的最后一个参数是一个 Lambda 表达式,因此可以省略函数调用时的括号,并将 Lambda 表达式移到函数调用的外部。

参数可选

函数中设置默认值的参数,在调用的时候可以不传。

没有设置默认值的参数都是必传的。

1
2
3
fun printInfo(name: String, age: Int = 18, city: String = "Unknown") {
println("Name: $name, Age: $age, City: $city")
}