Step 1 of 5 · Reading · ~4 min
Learn
Getting Started
val and var
Kotlin gives you two ways to introduce a name, and it very much wants you to pick the boring one. By the end of this lesson you can choose between them, read a number from input, and update a value as the program runs.
| Keyword | Can you reassign it? | Use it when |
|---|---|---|
val | no — assigned once | almost always; this is the default |
var | yes | the value genuinely has to change (a counter, a running figure) |
fun main() {
val name = "Ada"
var visits = 0
visits = visits + 1
visits += 1
println(name + " has visited " + visits + " times")
}
//> Ada has visited 2 times
visits + 1 is ordinary addition, and visits += 1 is shorthand for visits = visits + 1. The Numbers lesson covers arithmetic properly; here the point is the keyword. Joining text and a number with + works as long as the text comes first.
Try to reassign a val and the program does not build:
val name = "Ada"
name = "Grace" // error: val cannot be reassigned
That is a compile error, not a runtime one. The bug never reaches anybody.
What does val actually freeze?
val freezes the name, not the thing the name points at. A val is a label glued to one object. The label cannot be moved to a different object; if the object itself has moving parts, those parts still move. A String and an Int have no moving parts, so the distinction never bites here. It matters for collections, which the Lists and Arrays lesson picks up.
Types: inferred, but still there
Kotlin is statically typed. Every name has a type fixed at compile time; you just rarely have to write it down.
val city = "Oslo" // String
val year = 2016 // Int
val ratio = 0.75 // Double
val ready = true // Boolean
val initial = 'K' // Char — single quotes, exactly one character
You must write the type when you declare a name before you have a value for it, because there is nothing to infer from:
val label: String
label = "ready"
The core types are Int, Long, Double, Float, Boolean, Char and String. Kotlin has no int versus Integer split like Java's: Int is one type, and the compiler uses a machine primitive underneath wherever it can.
✓ / ✗
✓ Reach for val first and let the compiler tell you when you actually need var:
val label = "total"
✗ Declaring everything var "just in case" throws away help you were being given for free:
var label = "total" // nothing ever reassigns it
Reading input, and that !!
Every exercise reads standard input with readLine(). It hands back a String? — a string or nothing at all, because the input may have run out. The !! in the starters means "I promise a line is there; blow up if I am wrong":
val count = readLine()!!.toInt()
readLine()!! gives you a plain String, and .toInt() turns the text "7" into the number 7. Skip the conversion and you still hold text, and + on text glues rather than adds. The Null Safety lesson takes !! apart and shows the safer alternatives; for now read it as the starter's way of saying "the input is guaranteed".
Common mistakes
- Reassigning a
val. The compiler refuses; change the declaration tovaronly if the value really must change. - Dropping
.toInt(). The name then holds text, and+glues the pieces together instead of adding them:"7" + "5"is75. - Updating the wrong direction.
current -= amountandcurrent += amountlook alike and give opposite answers; read the sign out loud.
Your exercise
Stock Count reads three whole numbers and keeps a running figure in a var. The starter reads all three and converts them for you; you update the running figure twice and print it. The hidden tests send a negative result and a zero result, so print whatever number comes out rather than assuming it is positive.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…