Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Latest commit

 

History

History
65 lines (57 loc) · 4.43 KB

Upcoming Change Function Types Reform.md

File metadata and controls

65 lines (57 loc) · 4.43 KB
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 实施一个有用的反思库至关重要。简而言之,我们将统一FunctionXExtensionFunctionX在运行时以相同的方式表示,但不会影响我们创建的能力 类型安全的建设者 和其他类似 DSL 的结构。

为什么

目前,在kotlinkotlin-runtime.jar中有与FunctionX相关的 23 * 2 = 46 类文件和 46 个更多的类文件相关到ExtensionFunctionXX是 0 到 22 之间的数字)。这是很多类文件,但是在kotlin.reflect包(KFunctionXKMemberFunctionX中有 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;),否则您不需要更改代码中的任何内容 。 有关详细信息,请参阅 规格文件 (您可以对源进行评论,或者按“查看”进行渲染降价)。