我正在学习Go,我尝试了关于slices of slices的练习 . 我对主题本身(切片切片)没有任何问题 . 我很难理解函数调用 .
这是我练习的解决方案:
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
pic := make([][]uint8, dy)
for y := range pic {
pic[y] = make([]uint8, dx)
for x := range pic[y] {
pic[y][x] = uint8(5 * (x + y))
}
}
return pic
}
func main() {
//pic.Show(Pic(40,30)) // doesn't work, but why?
pic.Show(Pic) // works, but why? Where are the values for dx and dy set?
}
从第5行开始,有一个名为 Pic
的函数,它接收两个整数变量( dx
, dy
) . 所以我认为,正确的函数调用可能是 Pic(40,30)
( 40
和 30
是 dx
和 dy
的值) .
-
但为什么第17行会抛出错误? (
pic.Show(Pic(40,30))
) -
为什么直线18有效? (
pic.Show(Pic)
) -
dx
和dy
的值在执行第18行时从何而来?
我试图查找http://golang.org/x/tour/pic,将我重定向到https://godoc.org/golang.org/x/tour/pic . 在那里我可以读到,函数 show
是这样定义的:
func Show(f func(int, int) [][]uint8)
我理解为:
Show是一个需要一个参数的函数 . 此参数是一个需要两个类型为int的参数的函数,它必须返回一个类型为[] [] uint8的值(一片无符号8位整数的片) . 显示本身不会返回任何内容 .
所以,在这里,我再次读到内部函数( Show
的参数)需要两个参数 . 但是,当我尝试提供这些参数时,为什么会出现错误?为什么没有参数调用函数Pic是可以的?当执行Pic时,这些参数的值来自何处?
3 回答
当您说
Pic(40, 30)
时,您调用函数Pic
并返回[][]uint8
(如函数定义中所示) . 这意味着在您注释掉的代码中,您将[][]uint8
传递给Show
.当你说
Show(Pic)
时,你传递Pic
作为参数,这是一个函数 . 这就是Show
所期望的 .Pic
的类型为func(dx, dy int) [][]uint8
.Go允许您将函数作为参数传递,这就是这里发生的事情 .
你对
Show
的定义非常正确 - 它是一个接受另一种特定格式概念作为参数的函数 .Pic
是符合此条件的函数 - 因此您将其成功传递给Show
.但是当你调用
Pic(30,40)
时,这意味着不是一个函数,而是调用带有这些参数的函数的结果 . 所以在这种情况下,你传递给Show
而不是函数Pic
,而是它返回的切片[][]uint8
. 当然Show不能接受它 .你的函数
Pic
有两个参数,Show
需要一个参数 . 你用一个参数调用Show
,这是一个函数;该函数有两个参数 . 当您将函数传递给另一个函数时,假设您正在调用的函数(Show
)将调用您传入的函数(Pic
)并在进行该调用时提供必要的参数 .