本章节讲述 Kotlin中let&apply&run&also&with函数的相关知识
一.let函数
1.简介
let函数的实际上是一个作用域函数,当你需要去定义一个变量在一个特定的作用域范围内,let函数的是一个不错的选择,let函数另一个作用就是可以避免写一些判断null的操作。
2.结构
//使用场景1:在函数体内使用 it 替代 object对象 去访问其 公有 的 属性 和 方法
object.let{
it.XXX()
...
}
//使用场景2:判断object为null的操作
object?.let{//表示object不为null的条件下,才会去执行let函数体
it.tXXX
...
}
3.源码
/**
* Calls the specified function [block] with `this` value as its argument and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#let).
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
4.示例1
实体类
class People(name: String, age: Int) {
var name: String? = null
var age = 0
init {
this.name = name
this.age = age
}
}
调用
val person = People("张三", 34)
val resultLet = person.let {
it.age + 5
}
Log.d("KotlinActivity", "resultLet :$resultLet")
结果
D/KotlinActivity: resultLet :39
示例2
//使用let函数之前 textView非空分开写
textView?.setVisibility(View.VISIBLE)
textView?.setTextColor(Color.parseColor("#FFFFFF"))
textView?.setTextSize(14f)
//使用let函数之后 textView非空只写一个即可,it代替各种属性操作
textView?.let {
it.setVisibility(View.VISIBLE)
it.setTextColor(Color.parseColor("#FFFFFF"))
it.setTextSize(14f)
}
二.apply函数
1.简介
apply函数主要用来将多个步骤合并。
2.源码
/**
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#apply).
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
3.示例
//使用apply函数之前的写法 使用file对象set各种属性
val file = File("imgPath.txt")
file.setReadable(true)
file.setWritable(true)
file.setExecutable(true)
//使用apply函数之后的写法 使用apply函数在函数体内使用thisset各种属性
val file = File("hello.txt").apply {
this.setReadable(true)
this.setWritable(true)
this.setExecutable(true)
}
三.run函数
1.简介
用于在对象上执行一段代码,类似于let,但如果没有指定返回值,则返回块内最后一个表达式的结果或整个对象。
2.源码
/**
* Calls the specified function [block] with `this` value as its receiver and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#run).
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
3.示例
#使用run函数之前的原生Toast方法
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kotlin)
val makeText = Toast.makeText(
this,
"Toast",
Toast.LENGTH_SHORT
)
makeText.setGravity(Gravity.TOP, 0, 0)
makeText.show()
}
//使用run函数之后的原生Toast方法
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kotlin)
Toast.makeText(
this,
"Toast",
Toast.LENGTH_SHORT
).run {
setGravity(Gravity.TOP, 0, 0)
show()
}
}
四.also函数
1.简介
其作用是将一个对象作为参数传递给 Lambda 表达式,并返回该对象本身。
2.源码
/**
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#also).
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
3.示例
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kotlin)
val str = "字符串"
val length = str.also {
Log.d("KotlinActivity", "also函数内length:${it.length}")
}.length
Log.d("KotlinActivity", "also函数外length:$length")
}
4.结果
D/KotlinActivity: also函数内length:3
D/KotlinActivity: also函数外length:3
五.with函数
1.简介
用于调用一个对象的多个方法,而不需要重复对象引用。它不返回任何内容,并且当您需要对同一对象执行多个操作时非常有用。
2.源码
/**
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#with).
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return receiver.block()
}
3.示例
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kotlin)
val listOf = listOf("张三", "李四", "王五", "赵六", "孙七")
val obj = StringBuffer()
for (s in listOf) {
obj.append(s).append("\n")
}
val strResult01 = obj.toString()
Log.d("KotlinActivity", "普通方法遍历集合: $strResult01")
//with函数遍历集合
val strResult02 = with(StringBuffer()) {
for (s in listOf) {
append(s).append("\n")
}
toString()
}
Log.d("KotlinActivity", "with函数遍历集合: $strResult02")
}
4.结果
D/KotlinActivity: 普通方法遍历集合: 张三
李四
王五
赵六
孙七
D/KotlinActivity: with函数遍历集合: 张三
李四
王五
赵六
孙七
上述的几个函数,都是Standard.kt 文件中定义的函数,是Kotlin的标准函数。