什么".()"在Kotlin中意味着什么?

All*_*n W 15 android object higher-order-functions kotlin navigation-drawer

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

一个例子是Kotterknife:

private val View.viewFinder: View.(Int) -> View?
    get() = { findViewById(it) }
Run Code Online (Sandbox Code Playgroud)

其中我不太了解其功能,

MaterialDrawerKt

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

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

drawer {
    ...
}
Run Code Online (Sandbox Code Playgroud)

而不是给括号括起来的参数.

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

Kri*_*ofe 11

在Kotlin中没有任何东西并且什么都不返回的函数看起来像:

var function : () -> Unit
Run Code Online (Sandbox Code Playgroud)

虽然不同之处在于代码中的函数不返回任何内容,但只会在对象上调用它.

例如,

class Builder (val multiplier: Int) {

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

    fun multiply(value: Int) : Int {
        return value * multiplier
    }
}
Run Code Online (Sandbox Code Playgroud)

这里重要的是我们宣布"行动"类型的方式

action: (Builder.() -> Unit)
Run Code Online (Sandbox Code Playgroud)

这是一个什么都不返回的函数,除了在"Builder"类型的对象上调用之外什么也没有.

请参阅此处.


j2e*_*nue 11

这是一个很好的问题。所以当你有这样的声明时: T.()

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

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

 class MyObject {
        fun myFun(doSomething: MyObject.()->Unit) {
            doSomething()
        }

        fun doAnotherThing() {
            Timber.d("myapp", "doing another thing")
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

MyObject().myFun { doAnotherThing() }
Run Code Online (Sandbox Code Playgroud)

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

也可以这样做:

MyObject().apply{myFun { doAnotherThing() }}  
Run Code Online (Sandbox Code Playgroud)


Bol*_*ose 8

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

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

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

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)
}
Run Code Online (Sandbox Code Playgroud)


Pra*_*iya 5

@Kris Roofe 的回答使事情变得清晰。让我补充一点。

fun Activity.drawer表示我们drawerActivity类中制作扩展函数名。这就是我们可以直接从 Activity 类或 Activity 类的子类调用 drawer 方法的原因。

更多关于扩展功能在这里

(setup: DrawerBuilderKt.() -> Unit = {})在这个语句中我们可以看到 kotlin 高阶函数的威力。高阶函数的小介绍:-It is a function that takes functions as parameters, or returns a function.所以这里的setup param 是一个返回 Nothing 或Unit的函数(与 java 中的 Void 相同)。 DrawerBuilderKt.()表示可以使用DrawerBuilderKt类的对象调用该函数。= {}表示设置参数是可选的。因此该函数不接受任何参数并且不返回任何内容。

更多关于高阶函数在这里这里。更多关于可选参数here

私有 val View.viewFinder: View.(Int) -> View? 它将函数存储在属性中。这里有更多关于相同的信息。其余的和上面解释的一样。

希望这会有所帮助。