kotlin中操作符主要有run、with、let、also、apply

作用域函数

这些函数在调用函数的内部又提供了一个作用域
示例代码:

  1. fun test(){
  2. var animal = "cat"
  3. run {
  4. val animal = "dog"
  5. println(animal) // dog
  6. }
  7. println(animal) //cat
  8. }

上面例子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) }