Golang tour Switch order order: time.Now (). Weekday () + 2 gives runtime error: index out of range
I am studying Golang, was on a tour where I found a tutorial on Express Checkout . I changed it a bit (from Saturday to Sunday, for example) just to play around. It is printed too far. even on Sunday. So, I changed the code to look like this:
package main
import (
"fmt"
"time"
)
func main() {
day := time.Monday
fmt.Printf("When %v?\n", day)
today := time.Now().Weekday()
switch day {
case today + 0:
fmt.Println("Today.")
case today + 1:
fmt.Println("Tomorrow.", today + 1)
case today + 2:
fmt.Println("In two days.", today + 2)
default:
fmt.Println("Too far away.", today + 2)
}
}
Now it gives me the output:
When Monday?
Too far away. %!v(PANIC=runtime error: index out of range)
What can I do to change the index and not add it outside of the array? It seems to me that this is some kind of operator overloading. Should he do MOD, add operation, by default in case of days, at least?
source to share
This is the implementation details.
In this line
fmt.Println("In two days.", today + 2)
today
has a type time.Weekday
that it has int
as its base type, 2
an untyped integer constant, which will be converted to time.Weekday
and the addition will be done.
The implementation fmt.Println()
will check if the values passed to it implement fmt.Stringer
, but because time.Weekday
, its method String()
will be called, the implementation of which:
// String returns the English name of the day ("Sunday", "Monday", ...).
func (d Weekday) String() string { return days[d] }
Where days
is an array of 7 elements:
var days = [...]string{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
}
There is Weekday.String()
no range check because, for time.Saturday + 2
example, it is not a weekday. Weekday.String()
guarantees only correct operation for constants defined in the package time
:
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
If you want to make it work, you must use the remainder after dividing by 7, for example:
switch day {
case (today + 0) % 7:
fmt.Println("Today.")
case (today + 1) % 7:
fmt.Println("Tomorrow.", (today+1)%7)
case (today + 2) % 7:
fmt.Println("In two days.", (today+2)%7)
default:
fmt.Println("Too far away.", (today+2)%7)
}
source to share