kotlin - Kotlin 中 with 和 run 的区别

withrun 是否具有相同的功能,只是语法不同,或者 withrun 之间是否存在重大差异?

正确的方法是什么?

adapter.run {
    notifyDataSetChanged()
    if (activityDetails.isEmpty())
        emptyText.visibility = View.VISIBLE
    else 
       emptyText.visibility = View.GONE
}


with(adapter){
   notifyDataSetChanged()
   if (activityDetails.isEmpty())
       emptyText.visibility = View.VISIBLE
   else 
       emptyText.visibility = View.GONE
}

最佳答案

它们只有句法上的区别,run 是 extension function而 with 不是。以下是定义(在 kotlin-sdlib:1.0.3 中):

public inline fun <T, R> T.run(block: T.() -> R): R = block() // equivalent to this.block()

public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()

由于run是一个扩展函数,它多了一个T类型的隐式参数,所以参数类型是一样的。函数的主体实际上也是相同的。

它们的性能也应该相同,因为两者都是 inline functions : 生成的字节码应该只包含内联的 block 正文。


函数用法上的差异都是由于run是一个扩展造成的。

首先,run适用于调用链:

foo.run { bar }.run { baz }

其次,更重要的是,如果声明的变量类型具有具有相同签名的 run 函数,它将被调用而不是扩展。并且 run 可以被另一个扩展遮蔽。这是how extensions are resolved .示例:

class MyClass {
     fun <R> run(blockIgnored: MyClass.() -> R): Nothing = throw RuntimeException()
}

"abcdefg".run { println("x") } // prints "x"
MyClass().run { println("x") } // throws RuntimeException
(MyClass() as Any).run { println("x") } // prints "x"

https://stackoverflow.com/questions/38501764/

相关文章:

android - IllegalArgumentException : savedInstance

android - Kotlin : safe lambdas (no memory leak)?

kotlin - Kotlin 中的 'open' 和 'public' 有什么区别?

function - Kotlin:你可以为可变参数使用命名参数吗?

kotlin - 如果可空类型为空,我如何运行代码块?

java - 在使用 Kotlin 的方法中抛出异常

android - android 上的 Kotlin : Cannot find main mer

gradle - 为什么更新 Gradle 到 3.1.0 后显示 "3rd-party Gradl

class - 我无法从 Kotlin 的嵌套类中联系到任何类成员

android - 无法设置约束组的可见性