kotlin中扩展函数主要有run、with、let、also、apply
作用域函数
这些函数在调用函数的内部又提供了一个作用域
示例代码:
fun test(){
var animal = "cat"
run {
val animal = "dog"
println(animal) // dog
}
println(animal) //cat
}
上面例子test函数中有一个单独的作用域,在run函数中重新定义animal变量,可见它的作用域只存在于run函数中,run函数之外的值并没有改变。
在run函数当中它不仅仅只是一个作用域,他还有一个返回值。他会返回在这个作用域当中的最后一个对象。
例如现在有这么一个场景,用户领取app的奖励,如果用户没有登录弹出登录dialog,如果已经登录则弹出领取奖励的dialog。我们可以使用以下代码来处理这个逻辑。
run{
if (islogin) loginDialog else getAwardDialog
}.show
with
返回作用域的最后一个对象与let相似
与run比较
with(webView.settings){
javaScriptEnabled = true
databaseEnabled = true
}
webView.settings.run {
javaScriptEnabled = true
databaseEnabled = true
}
如果webView.setting可能为空
with(webView.settings){
javaScriptEnabled = true
databaseEnabled = true
}
webView.settings?.run {
javaScriptEnabled = true
databaseEnabled = true
}
also、apply、let
also 和 apply的差别主要存在于,lambda表达式内context表示方式,also与let是通过传入 的参数(it)来表示的,而apply是通过this来表示的。
also 可用于不更改对象的其他操作,例如记录或打印调试信息。通常,您可以在不破坏程序逻辑的情况下从调用链中删除也是调用。
val numbers = mutableListOf("one", "two", "three")
numbers.also { println("The list elements before adding new one: $it") }
.add("four")
但是let返回的是作用域中的最后一个对象,它的值和类型都是可以改变的,但是also不管点用多少次返回的都是与哪来的对象
val original = "abc"
original.let {
println("The original String is $it") // "abc"
it.reversed()
}.let {
println("The reverse String is $it") // "cba"
it.length
}.let {
println("The length of the String is $it") // 3
}
original.also {
println("The original String is $it") // "abc"
it.reversed()
}.also {
println("The reverse String is ${it}") // "abc"
it.length
}.also {
println("The length of the String is ${it}") // "abc"
}
apply的作用域的接受者是this,主要对接收器对象的成员进行操作。 apply的常见情况是对象配置。此类调用可以读作“将以下赋值应用于对象”
val adam = Person("Adam").apply {
age = 32
city = "London"
}
其他用法:
创建Fragment
// 使用普通的方法创建一个Fragment
fun createInstance(args: Bundle) : MyFragment {
val fragment = MyFragment()
fragment.arguments = args
return fragment
}
// 通过apply来改善原有的方法创建一个Fragment
fun createInstance(args: Bundle)
= MyFragment().apply { arguments = args }
创建Intent
// 普通创建Intent方法
fun createIntent(intentData: String, intentAction: String): Intent {
val intent = Intent()
intent.action = intentAction
intent.data=Uri.parse(intentData)
return intent
}
// 通过apply函数的链式调用创建Intent
fun createIntent(intentData: String, intentAction: String) =
Intent().apply { action = intentAction }
.apply { data = Uri.parse(intentData) }