【问题标题】:panic: runtime error: index out of range in Go恐慌:运行时错误:Go 中的索引超出范围
【发布时间】:2014-11-25 09:36:46
【问题描述】:

我有以下函数,它从终端接收命令并根据输入打印一些内容。看起来很简单,如果用户键入“添加”,系统会打印一行,如果用户什么都不键入,它会打印其他内容。

只要用户键入 add,它就会起作用。如果用户不输入任何内容,它会抛出

恐慌:运行时错误:GoLang 中的索引超出范围

这是为什么?

  func bootstrapCmd(c *commander.Command, inp []string) error {


     if inp[0] == "add" {
                  fmt.Println("you typed add")
              } else if inp[0] == "" {
                  fmt.Println("you didn't type add")
              }


          return nil

    }

【问题讨论】:

  • 这是你一生都会遇到的例外!不过,经过 100 多次之后,您会发展出第六感。

标签: go


【解决方案1】:

如果用户不提供任何输入,则inp 数组为空。这意味着即使索引0 超出范围,即无法访问inp[0]

您可以在检查inp[0] == "add" 之前使用len(inp) 检查inp 的长度。这样的事情可能会做:

if len(inp) == 0 {
    fmt.Println("you didn't type add")
} else if inp[0] == "add" {
    fmt.Println("you typed add")
}

【讨论】:

    【解决方案2】:

    你要先检查inp的长度:

    func bootstrapCmd(c *commander.Command, inp []string) (err error) {
        if len(inp) == 0 {
            return errors.New("no input")
        }
        switch inp[0] {
        case "add":
            fmt.Println("you typed add")
        case "sub":
            fmt.Println("you typed sub")
        default:
            fmt.Println("invalid:", inp[0])
        }
        return nil
    
    }
    

    【讨论】:

      【解决方案3】:

      您也可以使用recover() 来检查切片的现有索引

      func takes(s []string, i int) string {
          defer func() {
              if err := recover(); err != nil {
                 return
              }
          }()
          return s[i]
      }
      
      if takes(inp,0) == "add" {
         fmt.Println("you typed add")
      } else {
         fmt.Println("you didn't type add")
      }
      

      【讨论】:

      • 这是一个非常糟糕的建议,永远不要这样做。
      • @OneOfOne 你能解释一下为什么不好吗?
      • @PieceDigital 1. 它又贵又慢。 2.它鼓励了不应该使用的非常糟糕的编程习惯,您可以轻松查看if i < len(s) { return s[i] } return ""
      • 假设您正在解析一种二进制格式,其中 99.9999% 的长度由遥控器提供正确的长度,但偶尔会发送恶意数据包。总是做十几个长度检查会更好吗?还是用recover() 处理0.00001% 的情况?
      • 我不太确定发生恐慌是否比返回错误更昂贵:eli.thegreenplace.net/2018/… 我明白在 OP 提到的一次性情况下,恐慌将是一个糟糕的选择,但在解析器的情况下,它似乎是处理这种情况的首选方式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      • 2015-11-21
      • 2016-12-31
      • 1970-01-01
      相关资源
      最近更新 更多