kotlin-style-guide
kotlin-style-guide copied to clipboard
Using conditional statements
Prefer using the expression form of try, if and when. Example:
return if (x) foo() else bar()
The above is preferable to:
if (x)
return foo()
else
return bar()
Prefer using if for binary conditions instead of when. Instead of
when(x) {
null -> ...
else -> ...
}
use if (x == null) ... else ...
If the branches of an if statement are single expressions but don't both fit on the same line, indent the expressions by two levels (8 spaces) and the else keyword by one level (4 spaces):
val x = if (foo)
longExpressionOne()
else
longExpressionTwo()
In a when statement, if a branch is more than a single line, always separate it from adjacent case blocks with a blank line:
private fun parsePropertyValue(propName: String, token: Token) {
when (token) {
is Token.ValueToken ->
callback.visitValue(propName, token.value)
Token.LBRACE -> { // ...
}
Put short branches on the same line as the condition, without braces.
when(foo) {
true -> bar() //good
false -> { baz() } //bad
}
To me, the name of the issue is not very clear. Which statements exactly are meant?
I think loops deserve a separate issue where the pros and cons as well as use cases can be discussed. For example, you can use forEach with the safe-call operator.
Related SO questions:
http://stackoverflow.com/questions/34642868/how-do-i-do-a-break-or-continue-when-in-a-functional-loop-within-kotlin
http://stackoverflow.com/questions/34703867/how-to-continue-or-break-in-a-when-statement-inside-a-while-loop-using-k
Is using braces for when branches in scope for this issue? If yes, I would suggest not using braces for single statements.
when(foo) {
true -> bar() //good
false -> { baz() } //bad
}
Prefer using if for binary conditions instead of when.
This is not appropriate IMO:
when(boo) {
true -> ...
false -> ...
}
or
when(x) {
null -> ...
else -> ...
}
An additional issue with excessive use of when is that people may think that when is an analog of Scala's match case and is necessary for the smart cast to work, while in fact if provides exactly the same capabilities.
I heard about this misconception from a guy who read the 5th example in the docs section:
val hasPrefix = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
This is looks much better using if:
val hasPrefix = if(x is String) x.startsWith("prefix") else false
For me one of the most contentious issues is how to format if expression with moderately long single expression branches, like this
val scope = if (includeNonProjectItems)
GlobalSearchScope.allScope(project)
else
GlobalSearchScope.projectScope(project)
This zig-zag shape look ugly to me.
Placing this all on the single line does not work, the line is way too long:
val scope = if (includeNonProjectItems) GlobalSearchScope.allScope(project) else GlobalSearchScope.projectScope(project)
Something like this is probably better, but is not very symmetric:
val scope = if (includeNonProjectItems)
GlobalSearchScope.allScope(project)
else GlobalSearchScope.projectScope(project)
And, most surprisingly, when has just the right lovely oval shape here
val scope = when (includeNonProjectItems) {
true -> GlobalSearchScope.allScope(project)
else -> GlobalSearchScope.projectScope(project)
}
but is still ugly because it is a when and not an if.
You can use the other when syntax:
val scope = when {
includeNonProjectItems -> GlobalSearchScope.allScope(project)
else -> GlobalSearchScope.projectScope(project)
}
This is looks much better using if:
@voddan And even better not using if :)
val hasPrefix = x is String && x.startsWith("prefix")
@matklad in your example withif the indentation should highlight the value assignment, IMO:
val scope = if (includeNonProjectItems)
GlobalSearchScope.allScope(project)
else
GlobalSearchScope.projectScope(project)
Another options is to indent everything to full alignment:
val scope = if (includeNonProjectItems)
GlobalSearchScope.allScope(project)
else
GlobalSearchScope.projectScope(project)
@yole I like that ^^. The rule is if and else are on the same indentation level.
Not sure how it plays with #1 in case of an if-else multiline expression
Will this work?
val scope =
if (includeNonProjectItems)
GlobalSearchScope.allScope(project)
else
GlobalSearchScope.projectScope(project)
When I have a very long if-else, I format it this way:
val scope =
if (includeNonProjectItems) GlobalSearchScope.allScope(project)
else GlobalSearchScope.projectScope(project)
You can use the other
whensyntax:val scope = when { includeNonProjectItems -> GlobalSearchScope.allScope(project) else -> GlobalSearchScope.projectScope(project) }
What's the opinion about this?
I prefer using this instead of an if else branch.