【问题标题】:What does ".()" mean in Kotlin?“.()”在 Kotlin 中是什么意思?
【发布时间】:2017-11-09 16:14:16
【问题描述】:

我见过一个函数有一个由 ClassName.() 给出的参数的例子 这个好像不是扩展函数,就是ClassName.Function()

一个例子是Kotterknife:

private val View.viewFinder: View.(Int) -> View?
    get() = { findViewById(it) }

我不太了解的功能,

MaterialDrawerKt

fun Activity.drawer(setup: DrawerBuilderKt.() -> Unit = {}): Drawer {
    val builder = DrawerBuilderKt(this)
    builder.setup()
    return builder.build()
}

代码允许你直接调用的地方

drawer {
    ...
}

而不是给它用括号括起来的参数。

在任何地方都有这方面的文档吗?

【问题讨论】:

  • 你应该看看带有接收器的 lambdas:kotlinlang.org/docs/reference/…
  • 如果函数的最后一个参数是 lambda,您可以将其从括号中拉出并放入由 { } 包围的块中,如 drawer 示例中所示

标签: android object kotlin navigation-drawer higher-order-functions


【解决方案1】:

在 Kotlin 中一个不接受任何内容并且不返回任何内容的函数如下所示:

var function : () -> Unit

不同之处在于代码中的函数不接受任何内容,不返回任何内容,而是在对象上调用

例如,

class Builder (val multiplier: Int) {

    fun invokeStuff(action: (Builder.() -> Unit)) {
        this.action()
    }

    fun multiply(value: Int) : Int {
        return value * multiplier
    }
}

这里重要的一点是我们声明“动作”类型的方式

action: (Builder.() -> Unit)

这是一个不返回任何内容、不接受任何内容但在“Builder”类型的对象上调用的函数。

Refer more here.

【讨论】:

    【解决方案2】:

    这是个好问题。所以当你有这种说法时:T.()

    这意味着在你将传入的 lamda 中,“this”(即当前对象)将是 T 类型。让我们看看它是多么容易理解:

    假设我们有一个类,它有一个名为 myFun 的函数,它接收一个定义如下的 lambda:

     class MyObject {
            fun myFun(doSomething: MyObject.()->Unit) {
                doSomething()
            }
    
            fun doAnotherThing() {
                Timber.d("myapp", "doing another thing")
            }
        }
    

    要调用这个函数,我会这样做:

    MyObject().myFun { doAnotherThing() }
    

    看看它是如何知道将 MyObject() 引用用作“this”的。这实际上是在调用 this.doAnotherThing() ,这是刚刚创建的 Myobject() 实例。

    也可以这样做:

    MyObject().apply{myFun { doAnotherThing() }}  
    

    【讨论】:

    • 嗨,为什么你总是使用 doAnotherThing() 来调用它? doAnotherThing() 在这里有什么关系?没看懂
    • 我只是证明引用不需要使用 this.doAnotherThing() 只需 doAnotherThing()
    【解决方案3】:

    @Kris Roofe 的回答让事情变得清晰。让我添加更多内容。

    fun Activity.drawer 表示我们在Activity 类中创建了一个扩展函数名称drawer。这就是我们可以调用的原因 直接来自 Activity 类或 Activity 子级的抽屉方法 类。

    更多关于扩展函数here.

    (setup: DrawerBuilderKt.() -> Unit = {}) 在这个语句中我们可以看到 kotlin 高阶函数的威力。高等的小介绍 订购功能:- It is a function that takes functions as parameters, or returns a function. 所以这里 setup 参数是 返回 Nothing 或 Unit 的函数(与 Java 中的 Void 相同)。 DrawerBuilderKt.() 表示可以使用DrawerBuilderKt 类的对象调用该函数。 = {} 表示 setup 参数是 可选的。所以该函数不带参数,也不返回任何内容。

    更多关于高阶函数herehere。更多关于可选参数here

    private val View.viewFinder: View.(Int) -> View? 它将函数存储在属性中。 Here 更多信息。其余的和上面解释的一样。

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      有一个误解,认为 T.() -> Y 是 (T.()) -> Y,但实际上是 T.(()->Y)。 我们知道 (X)->Y 是一个 lambda,所以 T.(X)->Y 是 T 的扩展。

      如果没有参数,则形式为 T.() -> 是的

      有趣的是,我们可以用两种方式来称呼它。

      import kotlinx.coroutines.*
      
      
      open class MyClass(var name: String){
          open fun something(){println("myclass something")}
      }
      
      
      fun main() = runBlocking{
          val me = MyClass("Boll")
          val someMethod: MyClass.(Int) -> String = { n ->
              List(n){"X"}.joinToString(separator="", postfix=":${this.name}")
          }
          val some = me.someMethod(10)
          //val some = someMethod(me, 10)
          println(some)
      
          val anotherMehtod: MyClass.() -> String = { 
              "Y:"+this.name
          }
          //val another = me.anotherMehtod()
          val another = anotherMehtod(me) 
          println(another)
      }
      

      【讨论】:

      • 这真是一个有趣的发现。我很好奇 anotherMehtod(me) 的工作原理。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-02
      • 2020-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多