title | date | author | tags | keywords | categories | reward | reward_title | reward_wechat | reward_alipay | source_url | translator | translator_url |
---|---|---|---|---|---|---|---|---|---|---|---|---|
[译]Upcoming Change: Function Types Reform |
2015-04-09 07:26:00 -0700 |
Andrey Breslav |
官方动态 |
false |
Have a nice Kotlin! |
Kotlin M12 可能会带来另一个变化,这对 Kotlin 实施一个有用的反思库至关重要。简而言之,我们将统一FunctionX
和ExtensionFunctionX
在运行时以相同的方式表示,但不会影响我们创建的能力 类型安全的建设者 和其他类似 DSL 的结构。
目前,在kotlin
包kotlin-runtime.jar
中有与FunctionX
相关的 23 * 2 = 46 类文件和 46 个更多的类文件相关到ExtensionFunctionX
(X
是 0 到 22 之间的数字)。这是很多类文件,但是在kotlin.reflect
包(KFunctionX
,KMemberFunctionX
中有 46 * 3 = 138 个类文件>,KExtensionFunctionX
),这是顶部的<img alt =“:)”class =“wp-smiley”data-recalc-dims =“1”src =“https:// i2 .wp.com / blog.jetbrains.com / kotlin / wp-includes / images / smilies / simple-smile.png?w = 640&amp; ssl = 1“style =”height:1em; max-height:1em“ >
所以,一方面,我们真的需要在kotlin-runtime.jar
中减少类文件的数量。
那么,现在,ExtensionFunctionX
类型与FunctionX
类型无关,我们不能说listOfStrings.map(String :: length)
因为参数的类型为String。() - &gt; Int
,但是map()
expects (String) - &gt; Int
,这是悲伤,烦人和不便。
因此,我们希望将扩展功能强制为正常功能(带有一个额外的参数)。
在我们这样做的时候,我们也希望允许具有超过 22 个参数的功能,理论上可以是任意数量的参数(在 JVM 中实际上是 255)。
这里的一个重要约束是在 Java**中实现 Kotlin 函数必须保持简单:Java 8 lambdas 应该可以工作,在早期版本的 Java 新的 Function2(){...}
中只有在代码中的invoke()
方法就足够了。
所有 230 个功能类文件将被单个接口替代 功能 这将代表运行时的所有功能(+ 我们将保留 23 个接口kotlin.jvm.FunctionX
,以方便在 Java 中轻松创建 Kotlin 函数)。共赢得超过 200 个类文件。
现在,函数值(“(A) - &gt; B
”)和扩展函数值(“A.() - > B
”)在运行时相同的类型,这将允许使用它们几乎可互换。静态类型系统只会区分特征(例如,编译器将为任何 X 创建虚构的“类”代码 FunctionX,这将仅在编译时才会存在,永远不会作为类文件发布)。 由于编译时类型与运行时类型不完全相同,所以需要在
之类的运算符()中进行几个调整,因为
是必需的,但它们不会影响不是静态地知道涉及函数类型。
函数和扩展函数类型之间的语法区别将被保留(通过将A()→B
与注释的函数类型相结合):当 lambda 是类型时 - 根据预期的类型进行检查,该类型是扩展函数,类型推断会将这个
-receiver 添加到其签名中,而对于正常的函数,它会添加一个参数:
{% raw %}
{% endraw %}// Normal function:
fun call(callback: (Foo) -> Unit) { // callback has type `Function1<Foo, Unit>
...
}
// argument is a lambda with a normal parameter
call { foo -> println(foo) }
// Extension function
fun builder(body: Foo.() -> Unit) { // body has type `@extension Function1<Foo, Unit>`
...
}
// argument is an extension lambda: no parameters, but `this` is available
builder {
this.bar() // `this` has type Foo
}
{% raw %}
{% endraw %}这些变化会使功能的反思成为可能(即,KClass
将最终具有getFunctions()
),并且使用函数对象将更加直观。
除非您直接引用ExtensionFunctionX
类型(例如,例如ExtensionFucntion0&lt; Foo,Unit&gt;
),否则您不需要更改代码中的任何内容 。
有关详细信息,请参阅 规格文件 (您可以对源进行评论,或者按“查看”进行渲染降价)。