title | date | author | tags | keywords | categories | reward | reward_title | reward_wechat | reward_alipay | source_url | translator | translator_url |
---|---|---|---|---|---|---|---|---|---|---|---|---|
[译]Upcoming Change: Syntax For Annotations |
2015-04-03 06:13:00 -0700 |
Andrey Breslav |
官方动态 |
false |
Have a nice Kotlin! |
Kotlin 的注释语法灵感来自 C#,它围绕着它们的方括号:
{% raw %}
{% endraw %}[Inject]
fun setFoo(foo: Foo) { ... }
{% raw %}
{% endraw %}但是括号对于一个语言设计者而言是宝贵的,我们真的希望稍后再使用它们,因此我们正在考虑将注释语法更改为更类似 Java 的@
。
{% raw %}
{% endraw %}@Inject
fun setFoo(foo: Foo) { ... }
{% raw %}
{% endraw %}注意:不需要[...]
或@
的短语将被保留,所以你仍然可以说这个:
{% raw %}
{% endraw %}data class Foo
volatile var bar: Bar = ...
{% raw %}
{% endraw %}尽管如此,这种变化有一些影响。
首先,@
-syntax 已经在使用,对于标签:
{% raw %}
{% endraw %}@loop
for (i in 1..20) {
if (enough(i)) break@loop
println(i)
}
{% raw %}
{% endraw %}因为表达式可以被注释和声明,我们需要在这里改变一些东西。最简单的选择是将@
移到标签声明的末尾:
{% raw %}
{% endraw %}loop@
for (i in 1..20) {
if (enough(i)) break@loop
println(i)
}
{% raw %}
{% endraw %}请注意,使用网站(break @ loop
)没有更改,仍然看起来很不错<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&ssl=1”style =“height:1em; max-height:1em;“/>
我们还在研究如何在生成的.class
-file 中规定一个注释应该附加什么:
{% raw %}
{% endraw %}class C(@Ann("arg") var foo: Int)
{% raw %}
{% endraw %}我们在这里有很多选项:可以放置@Ann
注释
- 存储 foo 的字段
- 属性 foo 本身(不是 Java 声明)
- foo 的吸气剂
- foo 的设置者
- C 的主要构造函数的参数 foo
一些注释只适用于,例如,字段,对于那些没有问题,但有些允许许多可能的目标。为了表达意图,需要一些额外的语法。 一个选项是将注释类型名称与目标文件前缀:
{% raw %}
{% endraw %}class C(@field:Ann("arg") var foo: Int)
{% raw %}
{% endraw %}(许多目标可以用逗号分隔) 另一个选择是做 Scala 做的事情:
{% raw %}
{% endraw %}class C(@(Ann@field)("arg") var foo: Int)
{% raw %}
{% endraw %}- 下降:括号太多
- 颠倒:@field 也是一个注释(是的,Ann 是一个注释注释),这意味着更多的可扩展语法和较少的语言概念
另一个选择是使用@field
注释,其参数是该字段的注释:
{% raw %}
{% endraw %}class C(@field(@Ann("arg")) var foo: Int)
{% raw %}
{% endraw %}- 颠倒:比以前的情况更少的语言变化
- 缺点:如果相同的注释到达两个目标(例如吸气剂和设定器),则必须重复
这种方法的修改:
{% raw %}
{% endraw %}class C(@at(FIELD, @Ann1("arg"), @Ann2) var foo: Int)
class C(@atMany(array(FIELD, PROPERTY), @Ann1("arg"), @Ann2) var foo: Int)
{% raw %}
{% endraw %}那么定义如下:
{% raw %}
{% endraw %}annotation class at(val target: AnnotationTarget, vararg val annotations: Annotation)
annotation class atMany(val target: Array<AnnotationTarget>, vararg val annotations: Annotation)
{% raw %}
{% endraw %}而且,为了完整性,另一种方法涉及为声明域(内部属性)添加一个显式(可选)语法:
{% raw %}
{% endraw %}@Ann1("arg") @Ann2
val foo: Int = 1
@Ann1("arg") @Ann2
field _foo
@GetterAnnotation
get
{% raw %}
{% endraw %}- 缺点:在这里没有办法减轻重复
- 缺点:它很可能成为一个模糊的语法(像 $ backingField),它很少被使用,并且被工具支持很差
我们的用户似乎经常写这样的东西:
{% raw %}
{% endraw %}fun example() {
data class Example(val foo: String, val bar: Int) // Error on this line
...
}
{% raw %}
{% endraw %}这不正确解析,因为数据
不是一个关键字(既不是open
,btw),所以我们需要这样写:
{% raw %}
{% endraw %}fun example() {
@data class Example(val foo: String, val bar: Int) // OK
...
}
{% raw %}
{% endraw %}现在,如果我想要一个open
本地类,或者abstract
,那该怎么办?那些是修饰符,而不是注释,我们不能说@open
或@abstract
。
一个选项是允许使用@
转义修饰符以及注释:
{% raw %}
{% endraw %}fun example() {
@open class Example(val foo: String, val bar: Int)
...
}
{% raw %}
{% endraw %}其他选项包括允许与类同一行上的修饰符,但这并不直接扩展到函数, 现在表达 。查看更多 这里 ##
反馈欢迎
你怎么看? 美国 BTW,我们正在制定规范文件草案 这里