3.7 Kotlin讲堂:标准函数和静态方法
3.7.1 标准函数with、run和apply
let
标准函数的用法已经在上一章中介绍过了,不再赘述
with
函数
with
函数接收两个参数:第一个参数可以是一个任意参数的对象,第二个参数是一个lambda表达式。
示例代码如下:
val result = with(obj) {
// 这里是obj的上下文
”value“ // with函数的返回值
}
比如还是那个水果列表,现在我们要吃完所有水果,并将其打印出来
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
// 普通写法
val builder = StringBuilder()
builder.append("Start eating fruits.\n")
for (fruit in list) {
builder.append(fruit).append("\n")
}
builder.append("Ate all fruits.")
val result = builder.toString()
println(result)
来看输出
Start eating fruits.
Apple
Banana
Orange
Pear
Grape
Watermelon
Ate all fruits.
你会发现我们调用了很多次builder
对象的方法,这个时候就可以考虑用with
函数来让代码变得更加精简。
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val result = with(StringBuilder()) {
append("Start eating fruits.\n")
for (fruit in list) {
append(fruit).append("\n")
}
append("Ate all fruits.")
}
println(result)
with
写法:with
函数的第一个参数就是整个lambda表达式的上下文。with
和run
函数返回的都是lambda表达式的最后一行代码的返回值。
很明显第二段写法能让代码简洁不少。
run
函数
先来看格式:
val result = obj.run{
// 这里是obj的上下文
”value“ // run函数的返回值
}
可以看到run
函数的用法和with
函数十分类似。
首先,run
函数不是直接调用的,一定要调用某个对象的run
函数才行,其次run
函数只接收一个lambda参数。
来看示例代码:
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val result = StringBuilder().run {
append("Start eating fruits.\n")
for (fruit in list) {
append(fruit).append("\n")
}
append("Ate all fruits.")
}
println(result)
运行结果自然也是完全一致的。
apply
函数
apply
函数与run
函数类似,但是apply
函数无法指定返回值,而是会返回调用对象本身。
val result = obj.apply{
// 这是obj的上下文
}
// result == obj
我们再来改一下吃水果这段代码
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
val result = StringBuilder().apply {
append("Start earing fruits. \n")
for (fruit in list) {
append(fruit).append("\n")
}
append("Ate all fruits.")
}
println(result)
结果跟之前是一样的,不再演示。
实际应用场景:启动Activity。
val intent = Intent(appContext, MainActivity::class.java)
intent.putExtra("param1", "data1")
intent.putExtra("param2", "data2")
appContext.startActivity(intent)
可以用apply
函数简化成:
val intent = Intent(appContext, MainActivity::class.java).apply {
putExtra("param1", "data1")
putExtra("param2", "data2")
}
appContext.startActivity(intent)
标准函数介绍暂告一段落。
3.7.2 定义静态方法
Kotlin中弱化了静态方法这个概念,像工具类这种功能,在Kotlin中推荐使用单例类的方式来实现。
定义单例类。
Object Util {
fun doAction() {
Println("do action")
}
}
这样就能用Util.doAction()
的方式来调用了。
如果我们只是希望类中的某个方法是静态的该怎么办?可以用companion object
来实现,示例如下:
class Util2 {
fun doAction1() {
println("doAction1")
}
companion object {
fun doAction2() {
println("doAction2")
}
}
}
这样doAction2()
就能通过Util2.doAction2()
的方式来调用了。
其实
doAction2()
也还不是真正的静态方法,companion object
这个关键字会在Util
类的内部创建一个伴生类,而doAction2()
就是定义在这个伴生类里面的实例方法。只是Kotlin会保证Util
类始终只会存在一个伴生类对象,因此调用Util.doAction2()
方法实际上就是调用了Util
类中伴生对象的doAction2()
方法。
这些语法特性已经基本能满足我们平时的开发需求了,如果你确实需要定义真正的静态方法,Kotlin仍然提供了两种实现方式:注解和顶层方法。
class Util2 {
fun doAction1() {
println("doAction1")
}
companion object {
@JvmStatic
fun doAction2() {
println("doAction2")
}
}
}
只要在doAction2()
方法之上加上@JvmStatic
注解,那么doAction2()
方法就是一个真正的静态方法了。
Kotlin会将所有的顶层方法编译成静态方法,且Kotlin中所有的顶层方法都可以在任何位置被直接调用。
在Util2.kt
文件中定义一个doSomething()
方法,如下:
fun doSomething() {
println("doSomething")
}
class Util2 {
。。。
}
这样在Kotlin中就可以直接调用了,
在Java中使用Util2Kt.doSomething()
这种格式来调用就可以了。
3.8 小结与评论
适当休息,继续向前。
附上文中代码地址