doushan2224
2017-06-02 08:58
浏览 492
已采纳

Golang游览Switch评估顺序:time.Now()。Weekday()+ 2产生运行时错误:索引超出范围

I am learning Golang, was going through the tour where I found a tutorial on Switch evaluation order. I modified it a bit (e.g. Saturday to Sunday), just to play around. It printed Too far away. even for Sunday. So, I modified the code to look like this:

package main

import (
    "fmt"
    "time"
)

func main() {
    day := time.Monday

    fmt.Printf("When's %v?
", 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's Monday?
Too far away. %!v(PANIC=runtime error: index out of range)

What can I do to MOD the index, instead of adding it beyond array? Seems to me like some kind of operator overloading. Shouldn't it do MOD, on add operation, by default in case of days, at least?

图片转代码服务由CSDN问答提供 功能建议

我正在学习Golang,正在浏览的过程中找到了有关切换评估顺序的教程。 我做了一些修改(例如,星期六至星期日),只是为了玩转。 它甚至打印了太远了。 因此,我修改了代码,使其看起来像这样:

  package main 
 
import(
“ fmt” 
“ time” 
)
 
func main  (){
 day:= time.Monday 
 
 fmt.Printf(“%v?
”,day)
今天:= time.Now()。Weekday()
 
切换日期 {
今天的案例+ 0:
 fmt.Println(“ Today。”)
今天的案例+ 1:
 fmt.Println(“ Tomorrow。”,今天+ 1)
今天的案例+ 2:
  fmt.Println(“两天后。”,今天+ 2)
默认值:
 fmt.Println(“距离太远。”,今天+ 2)
} 
} 
   
 
 

现在,它给了我输出:

 星期一什么时候?
距离太远了。  %!v(PANIC =运行时错误:索引超出范围)
   
 
 

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

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongzhimin2231 2017-06-02 09:11
    已采纳

    This is an implementation detail.

    In this line

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

    today is of type time.Weekday which has int as its underlying type, 2 is an untyped integer constant, which will be converted to time.Weekday and the addition will be carried out.

    The implementation of fmt.Println() will check if values passed to it implement fmt.Stringer, and because time.Weekday does, its String() method will be called whose implementation is:

    // 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 no range check in Weekday.String() because time.Saturday + 2 for example is not a weekday. Weekday.String() only guarantees to work properly for the constants defined in the time package:

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

    If you want to make it work, you have to use the remainder after dividing by 7, like this:

    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)
    }
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题