Quotes decide the type
Kotlin treats text and numbers as different kinds of data. The difference shows up in how you write the value:
15, without quotes, is a number. A whole number like this is anInt."15", with double quotes, is aString: a sequence of the characters1and5.
They look alike when printed, but they behave differently. A number can be added, subtracted and compared by size. A string is text: Kotlin can join it to other text, measure its length or look at its characters, but it has no arithmetic value.
val a = 15
val b = "15"
println(a + 1) // 16
println(b + 1) // 151
In the first line, + adds. In the second, the string on the left makes + join text, so the result is the characters 15 followed by 1. The same symbol does a different job depending on the type.
Declared types are enforced
You can write the type after the variable name, separated by a colon:
val age: Int = 29
val phone: String = "2025550153"
Kotlin checks that the value matches the type you wrote. If it doesn't, the program is rejected before it runs. Consider the starter code of this lesson:
val age: Int = "29"
val phone: String = 2025550153
Both lines are wrong, and the compiler reports each one:
error: initializer type mismatch: expected 'Int', actual 'String'.
val age: Int = "29"
^^^^
error: initializer type mismatch: expected 'String', actual 'Int'.
val phone: String = 2025550153
^^^^^^^^^^
Each message says what the declaration expected and what the value actually is. Some languages quietly convert one into the other. Kotlin does not: you must write the value that really has the type you declared.
Fixing the exercise
The hint says the type annotations stay as they are, so only the values change. That is the right call because each declaration states a design decision:
ageis anInt. An age is a quantity. You might add a year to it, compare it with 18 or compute an average. Those operations need a number, so the value loses its quotes:29.phoneis aString. A phone number is an identifier, not a quantity. You never add two phone numbers or find their average. It may start with zeros or a plus sign, and a number type would lose those. Longer numbers with a country code can also exceed the largestInt, 2147483647. So the value gets quotes:"2025550153".
val age: Int = 29
val phone: String = "2025550153"
A good rule of thumb: if you might do arithmetic with the value, make it a number. If it is a label, a code or a sequence of characters, make it a string, even when it is made of digits.
Gotchas
- Digits in quotes are still text.
"29" + 1joins text and gives291, not 30. To get the number out of a string you convert it, which a later lesson covers. - Number plus string.
"a" + 1works and givesa1, because a string on the left accepts any value.1 + "a"does not compile:Inthas noplusthat takes a string. - Quote style. Strings use double quotes. Single quotes make a
Char, which holds exactly one character, so'29'is an error. - Whole numbers versus decimals.
29is anInt, while29.0is aDouble. Putting29.0into anIntvariable is the same kind of mismatch. - Inference. If you leave the annotation off, as in
val age = 29, Kotlin works the type out from the value, and the variable has that type from then on. The annotation is how you state your intention.
Key takeaways
- Quotes make a
String; no quotes with digits make a number. - Kotlin rejects a value that doesn't match the declared type, with an
initializer type mismatcherror. - Use numbers for values you calculate with and strings for identifiers such as phone numbers.