【问题标题】:Kotlin variables that are not in scope?不在范围内的 Kotlin 变量?
【发布时间】:2021-07-18 18:13:25
【问题描述】:

在 https://github.com/mozilla/rust-android-gradle/blob/8183f9e927336011c7c09d75efd4f5f411940db1/plugin/src/main/kotlin/com/nishtahir/CargoBuildTask.kt#L19 我们有这个 kotlin 代码:

open class CargoBuildTask : DefaultTask() {
    var toolchain: Toolchain? = null


    @Suppress("unused")
    @TaskAction
    fun build() = with(project) {
        extensions[CargoExtension::class].apply {

我很困惑extensions 和project 来自哪里。它们不是局部变量,它们不在范围内。它们是什么?

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    继承是project的答案。

    CargoBuildTask : DefaultTask()
    

    你看到CargoBuildTask 是如何继承DefaultTask 的属性的吗? 因此 project 是来自DefaultTask 的属性。但是,extensions 是来自 project 的属性,其类型为 Project。

    Read this documentation on DefaultTask and you will have more understanding.

    Kotlin 的with 是extensions 的答案。

    简而言之,使用with,您可以在不明确说明其主题的情况下调用方法。 (Read more here)

    例如,这两个代码sn-ps的意思完全一样:

        with("string") {
            substring(3) //invoke method without subject
        }
    
        "string".substring(3) //Same as above
    

    这是来自org.gradle.api.Project的方法

       ExtensionContainer getExtensions();
    

    现在,如果您想知道 Java 的 getExtensions() 是如何变成 Kotlin 的 extensions、read this 的。基本上说明Java中的传统Getters and Setters在Kotlin中被解释为Properties。

    PS:如果你不确定 Inheritance 在 OOP/Kotlin 中是什么,read this。

    【讨论】:

    • 不是扩展,extensions 来自project 作为with 的接收者,它是project 的属性,而不是DefaultTask。
    【解决方案2】:
    1. project来自当前类中继承的DefaultTask()。这里使用了继承,这是一个非常基本的概念。阅读更多关于 Kotlin 的继承here。

    2. extensions 来自 project 使用 with 这是范围函数之一。

      通过here 了解更多信息。 .

      例如。假设你有一个 Data 类。

      data class PersonModel(val name: String, var age: Int)
      

      然后你创建它的模型

      val personModel = PersonModel("Adam", 30)
      

      现在,如果您将其作为接收者传递给 with 函数,您可以直接在 with 的范围内访问 'personModel` 的属性:

      with(personModel) {
          //name is the property of personModel
          val nameWas = name
          //Declared var and can be editable.
          age = 31
      }
      

      with 也适用于函数,您可以将函数作为接收者传递给它,并返回函数的返回值。

      这些作用域函数(let、run、with、apply、also)在生产环境中非常有用。

    【讨论】:

      猜你喜欢
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多