【问题标题】: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 {

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

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    继承project的答案。

    CargoBuildTask : DefaultTask()
    

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

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

    Kotlin 的withextensions 的答案。

    简而言之,使用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 的 extensionsread 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 也适用于函数,您可以将函数作为接收者传递给它,并返回函数的返回值。

      这些作用域函数(letrunwithapplyalso)在生产环境中非常有用。

    【讨论】:

      猜你喜欢
      • 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
      相关资源
      最近更新 更多