kotlin-style-guide
kotlin-style-guide copied to clipboard
Using casts
Do not use free-standing as expressions for smart casts. Instead, assign a new name to the variable after the cast.
Good:
fun foo(x: Any) {
val s = x as String
s.length
}
Bad:
fun foo(x: Any) {
x as String
x.length
}
Isn't the generated equals method doing what the second example does?
I respectfully disagree.
If in the beginning of a function there is a cast x as String, it is basically an assertion to the function parameter. It describes the environment in which the function is used. Renaming of the parameter does not clarifies the change in type since x is always a String.
A similar situation:
fun foo(x: Any, y: Int?) {
x as? String ?: return
y ?: return
x + y
}
@voddan I personally find this syntax an abuse of smart casts. If this is really a common case (which I don't think it is), then we need to provide support for expressing this idea more cleanly.
You can do if (x !is String) return but that's a bit more verbose.
require(o is String) will not smart cast the value.
@yole Could you please explain why x as String is less readable?
It just doesn't look like an expression that does anything, which looks confusing. Yes, you can learn this pattern, and it is in fact concise, but it's just weird. (Also, as far as I understand, the fact that this works is an accident, and not an intention of the smart cast design.)
Similarly, val s = x as String looks like something that may or may not happen, when in fact it acts as an assertion. I understand why you don't like x as String, but I don't see how the other option is better.
@yole I'd consider this a happy accident in Language design and actually go ahead and add this pattern to https://kotlinlang.org/docs/reference/idioms.html as a recommended way to do type and nullability assertions (and checks with early returns) in function prologue code. Let it be idiomatic and it will not be confusing anymore.
IMO this should be fixed in the language (and AFAIK it's going to) so that assert(x is String) would make a smart cast. Until that x as String is just a workaround.