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

huangapple go评论70阅读模式
英文:

Golang panic: runtime error: index out of range

问题

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

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 
}

然而,我一直得到相同的错误,提示出现了恐慌:

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

英文:

This function takes an array with some integers and my goal is to have a new array with just positive integers:

func domath(newarray[] int, i int, array[] int)([]int){
    if i &lt; len(newarray) {
	    if newarray[i] &lt; 0{
	        i ++	
	        domath(newarray, i, array)
        }
        if newarray[i] &gt;= 0 {
	        array = append(array, newarray[i])
	        i ++
	        domath(newarray, i, array)
        }
    }
    return array 
}

However, I keep getting the same error saying panic:

> runtime error: index out of range

答案1

得分: 2

那个实现的问题在于它在第一个if块内部递增了i,然后使用新的i值来检查第二个if块中的newarray[i] >= 0,所以当你使用x = len(a)-1调用domath(a, x, b)时,它尝试执行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
}
英文:

The problem with that implementation is that it's incrementing i inside the first if block and then using the new i value to check newarray[i] >= 0 on the second if block, so when you call domath(a, x, b) with x = len(a)-1 it tries to do newarray[x+1] (i.e. newarray[len(newarray)]) which is out of bounds.

You probably meant to write something like:

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

A simplified version of your algorithm could be:

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

Yet you should probably be using an implementation more idiomatic like the following one, which will also be faster:

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

答案2

得分: 0

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

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)
}
英文:

Do you want write a recursive function?, you can see my code below :

func domath(newarray []int, i int, array []int) []int {
if i &lt; len(array) {
	if array[i] &gt;= 0 {
		newarray = append(newarray, array[i])
	}
	i++
} else {
	return newarray
}
return domath(newarray, i, array)

}

答案3

得分: 0

我解决了这个问题。这是一个简单但常见的错误。出现 golang panic 错误是因为我们忘记了"创建一个切片或数组"。例如:

package main

import "fmt"

func main() {
    var elementNumber int
    fmt.Println("你想要多少个元素?")
    fmt.Scanln(&elementNumber)

    storage := make([]int, elementNumber) // 这一行非常重要。
    for i := 0; i < elementNumber; i++ {
        fmt.Printf("请输入第 %d 个整数:", i+1)
        fmt.Scanln(&storage[i])
    }
}

如果我不使用"make",而是像下面这样写,它将无法工作:

package main

import "fmt"

func main() {
    var elementNumber int
    fmt.Println("你想要多少个元素?")
    fmt.Scanln(&elementNumber)

    storage := []int{}
    for i := 0; i < elementNumber; i++ {
        fmt.Printf("请输入第 %d 个整数:", i+1)
        fmt.Scanln(&storage[i])
    }
}

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

英文:

I solved this problem. It is simple but common mistake. The golang panic error coming out because of we missing the "make a slice or array". for example

package main

import &quot;fmt&quot;

func main() {
	var elementNumber int
	fmt.Println(&quot;How many elements do you want in slice?&quot;)
	fmt.Scanln(&amp;elementNumber)

	storage := make([]int, elementNumber) // this line crucial important.
	for i := 0; i &lt; elementNumber; i++ {
		fmt.Printf(&quot;please enter %d. integer number= &quot;, i+1)
		fmt.Scanln(&amp;storage[i])
	}
}

If I could have do instead this and do not use "make",it would have not work ;

package main

import &quot;fmt&quot;

func main() {
	var elementNumber int
	fmt.Println(&quot;How many elements do you want in slice?&quot;)
	fmt.Scanln(&amp;elementNumber)

	storage := []int{}
	for i := 0; i &lt; elementNumber; i++ {
		fmt.Printf(&quot;please enter %d. integer number= &quot;, i+1)
		fmt.Scanln(&amp;storage[i])
	}
}

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

huangapple
  • 本文由 发表于 2016年12月28日 13:51:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/41356117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定