Golang Tour练习问题探讨
Golang Tour练习问题探讨 我在完成Go语言之旅的这个练习时,遇到了代码无法运行的问题:
https://tour.golang.org/moretypes/18
主函数的调用只是运行了:pic.Show(Pic)。这是问题的一部分吗?既然Pic函数接受两个参数,那么它应该运行类似pic.Show(Pic(3,3))这样的代码才对?
当然,我已经尝试运行这段代码,但它失败了,所以我的代码也有问题。但我的代码非常简单,我不明白它怎么会出错,而且错误信息也帮不上忙:
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
output := [][]uint8{
[]uint8{0, 0, 0},
[]uint8{0, 255, 0},
[]uint8{0, 0, 0},
}
return output
}
func main() {
pic.Show(Pic)
}
panic: runtime error: index out of range [3] with length 3
goroutine 1 [running]: golang.org/x/tour/pic.Show(0x4eea60)
- /tmp/gopath773663214/pkg/mod/golang.org/x/tour@v0.0.0-20210305160921-b3263fcf7749/pic/pic.go:36 +0x1a6* main.main()
- /tmp/sandbox350473227/prog.go:27 +0x2d*
更多关于Golang Tour练习问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我想我已经回答了自己的问题。pic.Show 需要一个返回 [][]uint8 的函数,而不是 [3][3]uint8。考虑到这一点,我认为我之前要么是返回了一个返回 [3][3]uint8 的函数,要么就是直接返回了 [3][3]uint8,这两种情况都不对(我认为这就是“index out of range [3] with length 3”试图告诉我的信息)。
话虽如此,这仍然有点令人困惑,因为我仍然编写了一个返回有界数组的函数,但这个界限是由传递给函数的参数决定的。我仍然希望能了解为什么我的第一次尝试没有仅仅绘制一个 3x3 像素的正方形。
我的最终解决方案是:
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
var output [][]uint8
for len(output) < dy {
output = append(output, make([]uint8, dx))
}
for y:=0 ; y<dy; y++ {
for x:=0 ; x<dx; x++ {
output[y][x] = uint8((x+y))
}
}
return output
}
func main() {
pic.Show(Pic)
}
更多关于Golang Tour练习问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个典型的类型不匹配问题。pic.Show期望接收一个函数,该函数接受两个int参数并返回[][]uint8,但你的Pic函数返回的切片维度与传入的dx, dy参数不匹配。
错误信息显示索引越界,因为pic.Show内部会使用你提供的dx, dy值(比如256x256)来调用你的Pic函数,然后尝试访问返回的切片。但你的函数总是返回固定的3x3切片,当dx或dy大于3时就会导致越界。
正确的实现应该根据传入的dx, dy参数动态创建切片:
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
// 创建dy行的切片
pic := make([][]uint8, dy)
for y := range pic {
// 每行创建dx列的切片
pic[y] = make([]uint8, dx)
for x := range pic[y] {
// 这里设置每个像素的值
// 例如:(x+y)/2, x*y, x^y 等
pic[y][x] = uint8((x + y) / 2)
}
}
return pic
}
func main() {
pic.Show(Pic)
}
或者使用更简洁的写法:
func Pic(dx, dy int) [][]uint8 {
pic := make([][]uint8, dy)
for y := 0; y < dy; y++ {
row := make([]uint8, dx)
for x := 0; x < dx; x++ {
row[x] = uint8(x * y) // 或者 uint8(x^y), uint8((x+y)/2) 等
}
pic[y] = row
}
return pic
}
pic.Show(Pic)的调用是正确的,因为pic.Show期望接收一个函数(函数值),而不是函数的调用结果。它会内部使用测试用的dx, dy值来调用你的Pic函数。

