首页 文章

是否可以在Kotlin中传递内联函数?

提问于
浏览
0

在使用KotlinJs编写JavaScript代码时,我们通常必须仔细处理 this .

所以我们通常需要这个功能:

inline fun <T> thisAs() = js("this")

并在某处使用它:

this.click = {
    thisAs<MyVueComponent.Data>().username = "changed"
}

由于VueJs的内在逻辑,我必须生成JavaScript代码 this.usernamethis 是硬编码),但这很难看,我不想每次需要JavaScript时都写 thisAs<MyVueComponent.Data>().username this .

所以我尝试通过定义函数_2489443来改进它,如下所示:

external interface VueComponent<DATA, METHODS> {}

fun <DATA, METHODS> VueComponent<DATA, METHODS>.defineMethods(block: M.(() -> DATA) -> Unit): METHODS {
    val methods = jsObj<M>()
    block(methods, ::thisAs)
    return methods
}

我希望内联函数 thisAs 仍然是内联函数,即使我将它作为 ::thisAs 传递给 block ,所以我可以像这样重写代码:

this.methods = this.defineMethods { data ->
    this.click = {
        data().username += "changed!"  // I want to write `data()` to generate a JavaScript `this`
    }
}

但遗憾的是,函数 data (即 ::thisAs )不再内联,代码无法正常工作 .

有什么方法可以解决这个问题吗?


更新:

1 回答

  • 1

    我和你一样对象 this . 但是,我用lambda function with a receiver扩展了它(与Kotlin中用于类型安全的构建器相同的东西,除了我的函数返回 Unit 并且是内联的) .

    inline fun <T> withJsThis(body: T.() -> Unit) {
      js("this").unsafeCast<T>().body()
    }
    

    它可以很容易地在 methods 以及生命周期钩子中使用( createdmounted 等) . 它需要一行额外的代码,但它很干净,并且在从Kotlin转换为Javascript时产生完全预期的 this.variable .

    class LoginComponent {
    
      class Data {
        var username: String = "test@test.com"
        var password: String = ""
      }
    
      val data = {
        Data()
      }
    
      val template = """<form>
          <input type="text" v-model="username" placeholder="Email" />
    <input type="password" v-model="password" placeholder="Password" />
    <input type="submit" v-on:click.prevent="showInfo" /> </form>""" val methods = object { val showInfo: () -> Unit = { withJsThis<Data> { console.log("METHOD: USER = $username, PASS = $password") } } } fun mounted() { withJsThis<Data> { console.log("MOUNTED: USER = $username, PASS = $password") } } }

相关问题