title | date | author | tags | keywords | categories | reward | reward_title | reward_wechat | reward_alipay | source_url |
---|---|---|---|---|---|---|---|---|---|---|
More changes: Enum Syntax, Another Deprecation and More |
2015-04-07 06:34:00 -0700 |
Andrey Breslav |
官方动态 |
false |
Have a nice Kotlin! |
{% raw %}
{% endraw %}Currently the syntax for enums with non-trivial constructors is kind of monstrous:
{% raw %}
{% endraw %}enum class Message(val str: String) {
ERROR : Message("This is an error")
WARNING : Message("This is a friendly warning")
DEBUG : Message("Ignore this")
}
{% raw %}
{% endraw %}{% raw %}
{% endraw %}
We would really like to make it nicer, e.g. something like this:
{% raw %}
{% endraw %}enum class Message(val str: String) {
ERROR("This is an error")
WARNING("This is a friendly warning")
DEBUG("Ignore this")
}
{% raw %}
{% endraw %}Now, there are some technicalities, namely, enums can have other members:
{% raw %}
{% endraw %}enum class Example(...) {
A(...)
B(...)
fun foo() { ... }
}
{% raw %}
{% endraw %}The problem is that A
and B
can be parsed as annotations on foo()
. So, we had some options to consider here.
We are leaning toward putting a separator there between entries and other members:
{% raw %}
{% endraw %}enum class Example(...) {
A(...)
B(...)
; // this is mandatory
fun foo() { ... }
}
{% raw %}
{% endraw %}The semicolon is only necessary when some members follow it. Other options include requiring escaping on all annotations on members (and, possibly, modifiers too):
{% raw %}
{% endraw %}enum class Example(...) {
A(...)
B(...)
@inject fun foo() { ... }
}
{% raw %}
{% endraw %}This would be a little inconsistent with normal classes, traits etc. Or we could prefix enum entries with a (soft-)keyword:
{% raw %}
{% endraw %}enum class Example {
entry A
entry B
}
{% raw %}
{% endraw %}This looks too verbose. Another question here is how do we annotate enum entries themselves. Requiring escaping looks reasonable here:
{% raw %}
{% endraw %}enum class Example {
@Ann1 A
@Ann2(...) B
}
{% raw %}
{% endraw %}Other options include
- requiring a comma between enum literals (like in Java)
- requiring a newline between enum literals and allowing unescaped annotations on the same line
We have not decided which way to go on this one yet.
{% raw %}
{% endraw %}We are planning to implement continue
in when
-expressions as a jump to the next when
-entry. It is not implemented yet, but we want your code to stay unchanged when we add it, so for the time being, we prohibit using continue
in when
without a label that points to a loop:
{% raw %}
{% endraw %}loop@
for (...) {
when (...) {
... -> if (...) continue@loop else ... // OK
... -> if (...) continue // ERROR
}
}
{% raw %}
{% endraw %}We also prohibit unlabeled break
inside when
. While it is not decided whether we want to allow it ever, it seems like a better design to keep break
and continue
symmetric.
NOTE: A simple interpretation of break
inside when
is “stop matching and jump outside” (as in switch
in Java and C), but our when
often returns a value, and that would be unknown if we break out of it.
{% raw %}
{% endraw %}Well, we picked the names long time ago, and now what we call “trait” in Kotlin is not so much of a trait, and is exactly like Java’s interface nowadays, so we want to deprecate the usage of the trait
keyword, and introduce interface
in M12.
Feedback request: Let the flame begin