戈朗之旅 切换评估顺序:时间.现在().Weekday() + 2 产生运行时错误:索引超出范围



我正在学习Golang,正在浏览,在那里我找到了有关Switch评估顺序的教程。我稍微修改了一下(例如周六到周日),只是为了玩。它打印得太远了。 即使是星期天。因此,我将代码修改为如下所示:

package main
import (
"fmt"
"time"
)
func main() {
day := time.Monday
fmt.Printf("When's %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)
}
}

现在,它给了我输出:

When's Monday?
Too far away. %!v(PANIC=runtime error: index out of range)

我该怎么做来MOD索引,而不是将其添加到数组之外?在我看来,这就像某种运算符重载。它不应该在添加操作上默认执行 MOD,至少在几天的情况下?

这是一个实现细节。

在这一行中

fmt.Println("In two days.", today + 2)

today属于以int作为其基础类型的time.Weekday类型,2是一个非类型化的整数常量,它将转换为time.Weekday并将执行加法。

fmt.Println()的实现将检查传递给它的值是否实现fmt.Stringer,并且由于time.Weekday实现,因此将调用其String()方法,其实现为:

// String returns the English name of the day ("Sunday", "Monday", ...).
func (d Weekday) String() string { return days[d] }

其中days是一个包含 7 个元素的数组:

var days = [...]string{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
}

Weekday.String()没有范围检查,因为例如time.Saturday + 2不是工作日。Weekday.String()仅保证time包中定义的常量正常工作:

type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)

如果你想让它工作,你必须使用除以 7 后的余数,就像这样:

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)
}

最新更新