A compiler tells you whether the code you wrote is syntactically valid. A good compiler, however, doesn’t do just that; it also tells you at build time whether your code might run into a logical bug later on at runtime.
One such logical bug we often make as developers is not handling the possibility that map lookups yield nothing. Being a good compiler, kotlinc
knows that the entry you’re looking up in a map might not exist, and therefore errors out if it detects that you weren’t prepared for that possibility.
// Main.kt
fun main() {
val countryFlags: Map<Country, String> =
mapOf(
Country.BELGIUM to "π§πͺ",
Country.MALDIVES to "π²π»",
Country.PALESTINE to "π΅πΈ",
)
// β Type mismatch: inferred type is String? but String was expected
val flag: String = countryFlags[Country.BRAZIL]
println(flag)
}
enum class Country {
BELGIUM,
BRAZIL,
MALDIVES,
PALESTINE,
}
Other compilers have absolutely no issue with concealing that fact from you as a developer.
Here’s the same code in Java:
// Main.java
import java.util.Map;
void main() {
Map<Country, String> countryFlags = Map.of(
Country.BELGIUM, "π§πͺ",
Country.MALDIVES, "π²π»",
Country.PALESTINE, "π΅πΈ"
);
String flag = countryFlags.get(Country.BRAZIL);
System.out.println(flag); // null
}
enum Country {
BELGIUM,
BRAZIL,
MALDIVES,
PALESTINE,
}
and in TypeScript:
// index.ts
const countryFlags: Record<string, string> = {
BELGIUM: "π§πͺ",
MALDIVES: "π²π»",
PALESTINE: "π΅πΈ",
};
const flag: string = countryFlags["BRAZIL"];
console.log(flag); // undefined
And that, ladies and gentlemen, is just one of things that make programming in Kotlin an absolute delight.