“.()”在 Kotlin 中是啥意思?
Posted
技术标签:
【中文标题】“.()”在 Kotlin 中是啥意思?【英文标题】: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
示例中所示
【参考方案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().applymyFun 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 参数是 可选的。所以该函数不带参数,也不返回任何内容。
更多关于高阶函数here 和here。更多关于可选参数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) 的工作原理。以上是关于“.()”在 Kotlin 中是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章