kotlin-style-guide
kotlin-style-guide copied to clipboard
Using nullable Booleans
When you have a variable val value: Boolean? you have a couple of possible ways to test it for true:
if (value != null && value)(doesn't work with mutable properties)if (value ?: false)if (value == true)
I prefer version 3 because it makes the intent very clear.
In many cases you have an additional possibility: Write an extension function that works on nullable types. Example: nullableString.isNullOrEmpty()
I strongly prefer 2 because it is clear that you are dealing with a nullable boolean.
In contrast, 3 can be easily confused with a typical beginners mistake of if (condition == true).
@matklad I think that the inversion of the boolean that you have to do in option 2 (the statement is executed when the value is true, whereas the value that you have in the code is false) is significantly worse than the (quite harmless) uncertainly of the nullability of the value that might occur with option 3.
Can we have a bright highlighting in IDE for value == true in if (value == true), so that no one attempts to "refactor it"?
I don't think that's actually necessary, because the refactored code will not compile. We do need to highlight if (value == true) when value is a regular Boolean, with a quickfix to simplify.
I think it is somewhat a frustrating experience to attempt to refactor if(value == true) only to find out that no mistake was made. Without a visual clue those two situations are indistinguishable. The IDE code-smell warning may or may not be enough.
@yole hm, agree. Then it is the question of educating people about the fact that == true is an idiom and not a code smell.
And just a terrible idea, can a special syntax be invented for nullable booleans, like if (value?) perhaps?
We've discussed the possibility of handling nullable booleans in if in a special way, and decided that the current syntax is the most explicit about the actual handling of null (which can be different in different cases).
I think version 2 is actually quite clear, because the literal false is simply saying "false is the default when the value itself is missing (null)." This makes the alternative, using true as the default, equally clear: (value ?: true). Whereas with version 3, if the default should be true, then the correct condition is (value != false), which is arguably even stranger than (value == true).