title | date | author | tags | keywords | categories | reward | reward_title | reward_wechat | reward_alipay | source_url |
---|---|---|---|---|---|---|---|---|---|---|
[译]Kotlin M12 is out! |
2015-05-29 09:28:00 -0700 |
Andrey Breslav |
官方动态 |
false |
Have a nice Kotlin! |
我们很高兴地介绍Kotlin M12,带来一些相当重要的变化和新功能:
- 注释和枚举的新语法
- 更方便的功能类型语义
- 更好的聪明人
- kapt用于Java注释处理支持
- 多个IDE功能
- 和更多…
引入语言和核心库的许多更改都是弃用。使用 “代码清理...”操作 自动修复项目中的所有警告。
和我们一样 前面提到过 ,我们决定为未来更有效的使用预留方括号,并使Java用户的注释语法更加熟悉。所以,从M12开始,我们写 @Foo(args)</ code>而不是
[Foo(args)] </ code>。更多细节可以找到 这里 (甚至更多 - 在 规格文件 )。
请注意,在大多数情况下,
@ </ code>不需要</ strong>。通常我们编写注释而不进行任何转义:
{% raw %}
{% endraw %}
data class Foo // `data` is an annotation
{% raw %}
{% endraw %}
基于 [...] </ code>的旧语法已被弃用</ em>,因此编译器将在您的代码上发出警告。要修复这些警告,请按Alt + Enter并运行快速修复(个人或整个项目)。上述“代码清理...”动作也适用于整个项目。
由于M12 @name </ code>是一个注释,但它之前有一个含义,即它是一个 标签 。我们不得不为标签找到一些其他语法,现在他们在最后用 @ </ code>声明:
{% raw %}
{% endraw %}
loop@ for (i in 1..100) {
for (j in 1..100) {
if (...)
break@loop
}
}
{% raw %}
{% endraw %}
所以, loop @ </ code> 声明一个标签, break @ loop </ code> 使用</ em>。
在M12之前,Kotlin中的注释被允许使用 java.lang.Class </ code>,例如:
{% raw %}
{% endraw %}
annotation class handledBy(val handlerClass: Class<out Handler>)
// Usage
handledBy(javaClass<MyHandler>())
class MyEvent {...}
{% raw %}
{% endraw %}
现在,在Kotlin注释中不推荐使用Java特定的类,我们需要使用Kotlin自己的模型: kotlin.reflect.KClass </ code>而不是 java.lang.Class </ code>和<代码> Foo :: class </ code>而不是 javaClass&Foo&gt;()</ code>:
{% raw %}
{% endraw %}
annotation class handledBy(val handlerClass: KClass<out Handler>)
// Usage
handledBy(MyHandler::class)
class MyEvent {...}
{% raw %}
{% endraw %}
请注意,Kotlin看到Java注释,就像他们引用 KClass </ code>而不是 java.lang.Class </ code>一样:
{% raw %}
{% endraw %}
// Java
@interface JavaAnnotation {
Class<?> value();
}
{% raw %}
{% endraw %}
{% raw %}
{% endraw %}
// Kotlin
fun introspect(jann: JavaAnnotation) {
val theClass = jann.value // the type of this expression is KClass<*>
...
}
{% raw %}
{% endraw %}
现在,当我们需要将一个 KClass </ code>转换成一个 java.lang.Class </ code>时,我们可以调用它们的 .java </ code>。 Foo :: class.java </ code>或 jann.value.java </ code>。
我们决定使主构造函数的语法更加规则,现在主构造函数的完整表单</ em>包括构造函数</ code>关键字:
{% raw %}
{% endraw %}
class PrivateConstructor private constructor (val x: Int) {
...
}
{% raw %}
{% endraw %}
只有当我们想要注释</ strong>主要构造函数或添加修饰符时,完整的表单才是。在大多数情况下,旧的熟悉语法仍然有效:
{% raw %}
{% endraw %}
class MyClass(val x: Int) {
...
}
{% raw %}
{% endraw %}
由于我们的特征相当有限,Java的接口几乎相同,所以我们已经弃用了 trait </ code>关键字,所以请改用 interface </ code>。
像往常一样,快速修复和“清理代码...”将帮助您。
的 枚举的新语法 非常接近Java所拥有的。枚举条目现在应以逗号分隔:
{% raw %}
{% endraw %}
enum class Foo {
A, B, C
}
{% raw %}
{% endraw %}
现在,当你声明一个枚举</ code>类的成员时,它必须在所有条目之后,在最后一个条目之后必须有一个分号:
{% raw %}
{% endraw %}
enum class FooWithMember {
FOO,
BAR,
BAZ;
fun doIt() { ... }
}
{% raw %}
{% endraw %}
最后,当枚举</ code>具有构造函数时,可以通过简单地传递条目名称旁边的参数来调用它:
{% raw %}
{% endraw %}
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
// no members => semicolon is not needed here
}
{% raw %}
{% endraw %}
旧的语法已弃用。
我们统一了函数类型和扩展函数类型,所以现在它们通常可以互换使用。例如,我们可以传递 String :: length </ code>,其中函数'(String) - > Int'</ code>是预期的。
{% raw %}
{% endraw %}
// map() expects `(String) -> Int`
// argument has type `String.() -> Int`
strings.map(String::length)
{% raw %}
{% endraw %}
更多细节 这个帖子 。
如果您在Java代码中使用Kotlin的函数类(例如 kotlin.Function1 </ code>),则需要对其进行调整,因为从现在开始,这些类驻留在 kotlin.jvm.function </ code>包。您可以通过运行“清除代码...”来迁移所有Java代码,并使用“Java中使用已弃用的函数类”检查。
一个期待已久的功能:Kotlin现在可以智能铸造本地的 var </ code>:
{% raw %}
{% endraw %}
var foo = bar()
if (foo != null) {
foo.baz() // no error here
}
{% raw %}
{% endraw %}
当然,只有当编译器知道自相关检查后才能进行修改,智能转换只能起作用。请注意,循环通常会使图像失真(由于某些技术原因,我们无法使用完整的数据流分析进行智能转换),因此当循环中的 var </ code>被突变时,智能转换可能会不行。
公共和受保护的不可变的 val </ code>在同一个模块中的使用也可以被智能铸造:
{% raw %}
{% endraw %}
class C(public val d: D?)
fun foo(c: C) {
if (c.d != null) {
c.d.foo() // c.d has been smart-cast here
}
}
{% raw %}
{% endraw %}
功能表达式支持的内联和非本地返回 函数表达式 现在在M11中推出的内联电话支持:
{% raw %}
{% endraw %}
fun test(list: List<Foo?>) {
val mapped = list.map(fun (item) = item?.toString() ?: return@test) // non-local return
...
}
{% raw %}
{% endraw %}
M12删除以前不推荐的一些功能:
- 类对象被放弃赞成对象;
- 在匿名初始化程序块前面需要init。
一些更多的功能已被弃用:
- 打破和继续在何时;
- 扩展类的接口
- 协变型超类型专业化;
- 静态类型断言。
使用快速修复程序和“清理代码...”来迁移程序。
Kotlin有默认的参数大大地减少了重载中的需求,但是Java客户端不能直接从这个功能中受益
在M12中,我们添加了一个注释 jvmOverloads </ code>,指示编译器为具有N个默认参数的Kotlin函数生成N + 1重载。
例如,
{% raw %}
{% endraw %}
jvmOverloads fun f(a: String, b: Int = 0, c: String = "abc") {
...
}
{% raw %}
{% endraw %}
会产生
{% raw %}
{% endraw %}
// Java
void f(String a, int b, String c)
void f(String a, int b)
void f(String a)
{% raw %}
{% endraw %}
由于编译器发出的源映射表生成的类文件,我们现在可以逐步通过内联函数体。
一些技术说明:每个类文件都有分配给说明的行号。对于内联函数体,我们分配行数超出文件的实际结尾(例如,如果文件有50行,内联代码的行号以51开头),这些“虚拟”数字将映射到可能的内联代码的实际来源驻留在其他文件中。标准的JVM调试器可以了解源映射,并可以遍历相应的文件和行。唯一的注意事项是,异常堆栈跟踪可能有时包含超出文件结尾的行号。我们正在寻找解决这个问题的办法。
在Java中,注释是接口,它们的参数是这些接口的方法。因此,参数的排序是微不足道的,呼叫站点不能依赖它。这就是为什么Java要求所有的参数,但是一个(命名为 value </ code>)的命名。
虽然在Kotlin中声明的注释有适当的构造函数允许定位参数甚至是varargs,但是我们在这方面不能依赖Java注释,所以从现在开始,以下内容适用于Java注释:
- 只有名称值的参数才能被传递而不用名字,
- 只有名为value的参数可以是一个vararg(并且自动变为1,如果它是Java中的数组)
- 所有其他参数不能作为位置传递。
JavaScript后端正赶上JVM。 M12增加了支持
- 模块之间的内联工作
- 验证参数
- 函数表达式
- 次级施工人员
如前所述 这个帖子 ,M12为Annotation Processing添加了初始支持,因此现在,像Dagger 2这样的框架与Kotlin配合使用。当前实现的主要限制是Kotlin代码不能引用由注解处理器生成的任何声明(因此,对于Dagger,您需要在Java中至少写入一个小类)。
我们将来会通过为Kotlin编译器发出的类生成存根来解决这个限制。详细信息 上述职位 。
用于Android的Kotlin Gradle插件现在支持JUnit测试。我们需要做的就是遵循 Java的标准过程 ,但现在我们可以在Kotlin写我们的测试。
Kotlin最近的一些变化使我们的生态系统得到了很大的发展:现在 类星体 提供光纤(轻量级线程),Go-like频道,Erlang类演员和其他异步工具Kotlin!见公告 这里 。
M12为标准库添加了新功能:
- 新的实用程序在kotlin.io包
- 新的文本实用程序
- 正则表达式API通过JVM和JS统一
- 新的收集工具
- 对于JVM和JS的所有数字类型,MIN_VALUE和MAX_VALUE都可用
当我们在Kotlin标准库上工作时,有些事情会被改变和/或不赞成。使用快速修复程序和“清理代码...”操作来迁移代码。 (请确保已将标准库的源附加到项目中。)
完整的更改列表可用 这里 。
Kotlin IDE现在支持标准的引用参数</ strong>重构,将将函数内选择的表达式转换为参数:
{% raw %}
{% endraw %}
另外,引入Lambda参数</ strong>可用于提取一段代码作为函数值:
{% raw %}
{% endraw %}
重命名</ strong>还可以重命名相关声明(变量,子类等):
{% raw %}
{% endraw %}
由于我们最近添加了很多弃用资料,IDE现在支持 ReplaceWith </ code> quick-fix:对于已弃用的</ code>注释,有一个(可选的)额外的参数,我们可以指定一个表达式替换已弃用的调用:
{% raw %}
{% endraw %}
有一个意图是将 ReplaceWith </ code>添加到用户不推荐的声明中。
一些更改:
- 新的调试器功能
评估本地功能的表达式
现场观察点(仅适用于具有后备字段的属性)
- 评估本地功能的表达式
- 现场观察点(仅适用于具有后备字段的属性)
- 更改包意图
- 突出显示出口点的功能
- Gutter标记用于递归调用
- 未使用的接收机参数检查
- 导入的代码样式设置(例如,我们现在可以随时使用'*'导入指定的包)
- Java2Kotlin转换器现在提供更新其他文件的用法
- 当完成列表打开时键入'!'插入否定调用(例如!foo.isEmpty())
- 改变可见度修饰符的意图操作
- 意图行动现在有更好的可用性
- 当超类“构造函数”具有参数时,可以快速修复从基类添加参数
我们仍在努力解决我们先前宣布的一些变化 Java的更安全 。一旦他们准备好就会把它们出来。
在最近的将来会出现一些更多与M12有关的材料。敬请关注!