【问题标题】:Golang panic: runtime error: index out of rangeGolang 恐慌:运行时错误:索引超出范围
【发布时间】:2017-05-12 09:16:45
【问题描述】:

这个函数接受一个包含一些整数的数组,我的目标是创建一个只有正整数的新数组:

func domath(newarray[] int, i int, array[] int)([]int){
    if i < len(newarray) {
        if newarray[i] < 0{
            i ++    
            domath(newarray, i, array)
        }
        if newarray[i] >= 0 {
            array = append(array, newarray[i])
            i ++
            domath(newarray, i, array)
        }
    }
    return array 
}

但是,我不断收到同样的错误提示:

运行时错误:索引超出范围

【问题讨论】:

  • 看来你没有处理长度为 0 的数组

标签: go runtime panic


【解决方案1】:

该实现的问题在于它在第一个 if 块内递增 i,然后使用新的 i 值检查第二个 if 块上的 newarray[i] >= 0,所以当您调用 domath(a, x, b) 对于 x = len(a)-1,它会尝试执行超出范围的 newarray[x+1](即 newarray[len(newarray)])。

你可能打算写这样的东西:

func domath(newarray []int, i int, array []int) []int {
    if i < len(newarray) {
        if newarray[i] < 0 {
            return domath(newarray, i+1, array)
        }
        if newarray[i] >= 0 {
            array = append(array, newarray[i])
            return domath(newarray, i+1, array)
        }
    }
    return array
}

您的算法的简化版本可能是:

func domath(newarray []int, i int, array []int) []int {
    if len(newarray) == i {
        return array
    }
    if newarray[i] >= 0 {
        array = append(array, newarray[i])
    }
    return domath(newarray, i+1, array)
}

然而,您可能应该使用更惯用的实现,例如以下实现,它也会更快:

func domath(ns []int) []int {
    var ps []int
    for _, n := range ns {
        if n >= 0 {
            ps = append(ps, n)
        }
    }
    return ps
}

【讨论】:

    【解决方案2】:

    你想写一个递归函数吗?你可以在下面看到我的代码:

    func domath(newarray []int, i int, array []int) []int {
    if i < len(array) {
        if array[i] >= 0 {
            newarray = append(newarray, array[i])
        }
        i++
    } else {
        return newarray
    }
    return domath(newarray, i, array)
    

    }

    【讨论】:

      【解决方案3】:

      我解决了这个问题。这是一个简单但常见的错误。由于我们缺少“制作切片或数组”而出现的 golang 恐慌错误。例如

      package main
      
      import "fmt"
      
      func main() {
          var elementNumber int
          fmt.Println("How many elements do you want in slice?")
          fmt.Scanln(&elementNumber)
      
          storage := make([]int, elementNumber) // this line crucial important.
          for i := 0; i < elementNumber; i++ {
              fmt.Printf("please enter %d. integer number= ", i+1)
              fmt.Scanln(&storage[i])
          }
      }
      

      如果我可以这样做而不使用“make”,它就行不通了;

      package main
      
      import "fmt"
      
      func main() {
          var elementNumber int
          fmt.Println("How many elements do you want in slice?")
          fmt.Scanln(&elementNumber)
      
          storage := []int{}
          for i := 0; i < elementNumber; i++ {
              fmt.Printf("please enter %d. integer number= ", i+1)
              fmt.Scanln(&storage[i])
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-21
        • 2016-12-31
        • 2013-09-03
        相关资源
        最近更新 更多