巡回赛中的函数调用,练习"切片和#34;

时间:2017-10-25 15:00:12

标签: function go

我正在学习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的函数,它接收两个整数变量(dxdy)。所以我认为,正确的函数调用可能是Pic(40,30)4030dxdy的值。

  • 但为什么第17行会出错呢? (pic.Show(Pic(40,30))
  • 为什么直线18有效? (pic.Show(Pic)
  • 执行第18行时,dxdy的值来自何处?

我尝试查找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本身并不会返回任何内容。

所以,在这里,我再次读到内部函数(Show的参数)需要两个参数。但是,当我尝试提供这些参数时,为什么会出现错误?为什么没有参数调用函数Pic是可以的?当执行Pic时,这些参数的值来自何处?

3 个答案:

答案 0 :(得分:3)

当您说Pic(40, 30)时,您调用函数Pic并返回[][]uint8(如函数定义中所示)。这意味着您在已注释掉的代码中将[][]uint8传递给Show

当您说Show(Pic)时,您将Pic作为参数传递,这是一个函数。这就是Show所期望的。 Pic的类型为func(dx, dy int) [][]uint8

Go允许您将函数作为参数传递,这就是这里发生的事情。

答案 1 :(得分:1)

你对Show的定义非常正确 - 它是一个接受另一种特定格式概念作为参数的函数。 Pic是符合此条件的函数 - 因此您已成功将其传递给Show

但是当你调用Pic(30,40)表示不是函数而是调用带有这些参数的函数的结果时。因此,在这种情况下,您传递给Show而不是函数Pic,而是传递给它[][]uint8的切片。当然Show不能接受它。

答案 2 :(得分:0)

您的功能Pic有两个参数,Show需要一个参数。您使用单个参数调用Show,这是一个函数;该函数有两个参数。当您将函数传递给另一个函数时,假设您调用的函数(Show)将调用您传入的函数(Pic)并在函数生成时提供必要的参数那个电话。