在Golang中,为什么这样的类型转换会导致运行时错误:索引超出范围?

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

In Golang, why such Type Conversion causes Runtime Error: index out of range?

问题

我正在做《Go之旅》中的练习,我所在的页面是https://tour.golang.org/moretypes/15

以下是我的代码:

package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
    var ret [][]uint8
    var row []uint8
    for i := uint8(0); i < uint8(dy); i++ {
        row = []uint8{}
        for j := uint8(0); j < uint8(dx); j++ {
            row = append(row, i+j)
        }
        ret = append(ret, row)
    }
    return ret
}

func main() {
    pic.Show(Pic)
}

当我运行这些代码时,控制台会抛出一个错误:

panic: runtime error: index out of range

goroutine 1 [running]:
panic(0x18b820, 0x1040a010)
    /usr/local/go/src/runtime/panic.go:464 +0x700
golang.org/x/tour/pic.Show(0x1d7948, 0x104000e0)
    /go/src/golang.org/x/tour/pic/pic.go:24 +0x540
main.main()
    /tmp/sandbox969725880/main.go:19 +0x20

有人知道为什么会出现这个错误吗?这是因为int->uint8类型转换吗?谢谢!

英文:

I was doing the exercise of "A Tour of Go", the page I was on is https://tour.golang.org/moretypes/15

And following is my code:

package main

import &quot;golang.org/x/tour/pic&quot;

func Pic(dx, dy int) [][]uint8 {
	var ret  [][]uint8;
	var row []uint8;
	for i:=uint8(0);i&lt;uint8(dy);i++ {
		row = []uint8 {}
		for j:=uint8(0);j&lt;uint8(dx);j++ {
			row = append(row, i+j)
		}
		ret = append(ret, row)
	}
	return 	ret
}

func main() {
	pic.Show(Pic)
}

When I run these codes, the console throws an error:

panic: runtime error: index out of range

goroutine 1 [running]:
panic(0x18b820, 0x1040a010)
    /usr/local/go/src/runtime/panic.go:464 +0x700
golang.org/x/tour/pic.Show(0x1d7948, 0x104000e0)
    /go/src/golang.org/x/tour/pic/pic.go:24 +0x540
main.main()
    /tmp/sandbox969725880/main.go:19 +0x20

Does anyone have any ideas why does the error occur for this int->uint8 type conversion?Thanks!

答案1

得分: 4

uint8的最大值为255(只有8位,最大为2^8),但是传入Pic函数的dx和dy的值可能大于255(因为它们是int类型,可能有64位)。大于255的值在转换为uint8时可能会被转换为0。如果dy的值为256并且被转换为0作为i,那么外部的for循环将不会执行,数组中也不会有任何元素被添加进去。随后,在“golang.org/x/tour/pic”中的任何机制尝试在返回后访问矩阵中的值时,会出现“索引超出范围”的错误,因为矩阵中实际上没有索引可供访问。

修正后的代码:

package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
	var ret [][]uint8

	for i := 0; i < dy; i++ {
		row := []uint8{}
		for j := 0; j < dx; j++ {
			row = append(row, uint8(i+j))
		}
		ret = append(ret, row)
	}
	return ret
}

func main() {
	pic.Show(Pic)
}
英文:

uint8 has a max value of 255 (only 8 bits, max 2^8) but dx, dy passed into Pic can have values greater than that (since they're int's, likely 64 bits). Values greater than 255 might get cast to 0 during conversion to uint8. If dy is 256 and it's cast to 0 as i, the outer for loop doesn't execute at all and no items get pushed into the array. Subsequently, when whatever mechanism in "golang.org/x/tour/pic" tries to access the values in the matrix after it's returned, it looks like it's generating an 'index out of range' error because there are literally no indexes in the matrix to access.

Working code:

package main

import &quot;golang.org/x/tour/pic&quot;

func Pic(dx, dy int) [][]uint8 {
	var ret [][]uint8

	for i := 0; i &lt; dy; i++ {
		row := []uint8{}
		for j := 0; j &lt; dx; j++ {
			row = append(row, uint8(i+j))
		}
		ret = append(ret, row)
	}
	return ret
}

func main() {
	pic.Show(Pic)
}

huangapple
  • 本文由 发表于 2016年4月1日 13:25:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/36348691.html
匿名

发表评论

匿名网友

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

确定