Constants
Some values never change while a program runs — the number of hours in a day,
a conversion factor, a status code. Go gives those a home: const.
package main
import "fmt"
const HoursPerDay = 24
func main() {
fmt.Println("three days is", 3*HoursPerDay, "hours")
}
A constant is fixed at compile time. Assigning to it later (HoursPerDay = 25) is a compile error, and so is initializing one from anything the
compiler can't compute itself — const t = time.Now() won't build, because
time.Now() only has an answer at run time.
No := for constants
You might reach for HoursPerDay := 24 out of habit. It won't compile — and
the reason is worth knowing. := declares a variable: it allocates a slot
whose contents can change. A constant isn't a slot at all; it's a name the
compiler substitutes wherever it appears, more like careful find-and-replace
than storage. Since the two are fundamentally different things, Go gives them
different syntax: := for variables, const ... = for constants.
Untyped constants are flexible
Here's a superpower variables don't have. Remember that Go never mixes int
and float64 implicitly? Constants soften that rule:
package main
import "fmt"
const Scale = 2 // untyped — no type written, so none fixed yet
func main() {
votes := 10 // int
turnout := 0.75 // float64
fmt.Println(votes * Scale) // Scale acts as an int here
fmt.Println(turnout * Scale) // ...and as a float64 here
}
Scale is an untyped constant: it has a default kind (integer) but no
fixed type until the moment it's used, and at that moment it adopts whatever
type the context needs. A variable scale := 2 could never do this — the
second fmt.Println line would be a mismatched-types compile error. This is
why constants like math.Pi work smoothly with every float type. (You can
pin a type — const Scale int = 2 — and then it behaves as strictly as any
int.)
iota: enumerations without the counting
When you need a family of related constants — days, states, sizes — Go has a
counter called iota. Inside a const block it starts at 0 and increments
by one for each line:
package main
import "fmt"
type Size int
const (
Small Size = iota // 0
Medium // 1 — the "= iota" repeats implicitly
Large // 2
)
func main() {
fmt.Println(Small, Medium, Large) // 0 1 2
}
Two things to notice. First, type Size int declares a named type so these
constants aren't bare ints — a function taking a Size documents itself.
Second, after the first line the expression repeats implicitly: you write
= iota once and the rest of the block just lists names. Reordering or
inserting a value renumbers everything automatically, which is exactly what
you want from an enumeration — no hand-maintained 0, 1, 2, ... to get
wrong.
The exercise puts iota to work on the seven days of the week.
Practice
1. Weekdays with iota
BeginnerTwo parts.
1. Declare the enum. Using the named type already provided:
type Weekday intrewrite the placeholder
constblock so the seven constantsSunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturdayare declared withiota, givingSundaythe value0,Mondaythe value1, ... andSaturdaythe value6.2. Implement the function with exactly this signature:
func isWeekend(d Weekday) boolIt returns
trueforSaturdayandSunday, andfalsefor every other day.package main import "fmt" // Weekday numbers the days of the week, Sunday = 0 through Saturday = 6. type Weekday int // TODO: rewrite this block to use iota so that Sunday is 0, Monday is 1, // ... and Saturday is 6. Right now every day is a placeholder 0. const ( Sunday Weekday = 0 Monday Weekday = 0 Tuesday Weekday = 0 Wednesday Weekday = 0 Thursday Weekday = 0 Friday Weekday = 0 Saturday Weekday = 0 ) // isWeekend reports whether d falls on the weekend. func isWeekend(d Weekday) bool { // TODO: implement — Saturday and Sunday are the weekend. return false } func main() { fmt.Println("is Sunday a weekend day?", isWeekend(Sunday)) }Sign in to write and run your solution in the browser.
Sign in for hints and the solution.