Golang实战练习 #9:什么是回调函数及其应用

Golang实战练习 #9:什么是回调函数及其应用 我很清楚自己在这个网站上的水平远低于大多数人,事实上,我很可能是最差的。但我决心学习Go语言,所以经常需要大家的帮助。

题目要求:“在本练习中,*将一个函数作为参数传递给另一个函数”

这是我在观看教学视频和老师提供的解决方案前,自己尝试完成的练习:https://play.golang.org/p/WMXMg6qn2N9

我的想法是给这些数字:1, 2, 3, 4, 5, 6, 7, 8, 9 都加上42,虽然我也不知道这个想法是从哪来的。

问题一:我的想法是否符合老师的要求?

问题二:如果符合,我哪里做错了?

问题三:如果不符合,我仍然想知道如何用我的想法完成这个任务。同时我会更认真地研究老师的解决方案。

顺便附上老师的解决方案:https://play.golang.org/p/0yGYPKh1y7

我知道回答我的问题可能需要各位帮助者极大的耐心,但想到"耐心是一种美德"这句话,我就感到些许安慰。


更多关于Golang实战练习 #9:什么是回调函数及其应用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

明白了!谢谢!!!

更多关于Golang实战练习 #9:什么是回调函数及其应用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


坚持下去,你的坚韧精神令人耳目一新。😊

https://play.golang.org/p/c7sYmpnWD33

这确实很有帮助!!谢谢!!

刚刚挤出了一些额外时间。
感谢你的推荐。托德是个聪明体贴的人,他还加入了一些令人耳目一新的幽默。
这些链接很有帮助!
https://play.golang.org/p/c7sYmpnWD33
谢谢你提供的这个,它真的很有用!
当我终于理解时,我真是太开心了!

https://play.golang.org/p/0yGYPKh1y7

在我阅读上面的回复之前,由于时间有限,我对老师的解决方案有个疑问。老师说这段代码:

return xi[0] + xi[len(xi)-1]

返回的是第一个元素和最后一个元素。可能因为我的时间太有限了,我无法理解其中的原因。

是的,我正在上Todd McLeod的课程。
我很喜欢你的幽默感。
感谢你清晰地演示了如何将函数作为参数传递。
我有个问题,不太确定该怎么表达。是这样的:
当你包含一个像这样的"代码框"时:

func add42(number int) int {
    return number + 42;
}

我是应该直接阅读这些信息呢?还是应该把它放到Playground上?如果是后者,我该怎么做?复制粘贴吗?
另一个问题。在Go Playground中,func main()之上或之前的区域有特定的名称吗?
我不确定什么时候应该把函数、声明等"信息"放在那里,或者放在func main()之后。
我知道我听起来可能很笨。
但我感觉开始慢慢理解了。

哈哈!我也这么觉得,那门课程真的很棒,我会向任何想学习Go语言的人推荐它。

当我使用代码框时,是为了隔离一小段代码片段,希望能在其他代码的干扰之外更易于理解。

这样做很有帮助,因为你可以分解代码的各个组成部分并单独分析它们。

这些代码片段始终是有效的Go代码,所以理论上你完全可以将它们复制粘贴到Go Playground中,而且应该能完美运行。

我总是尽量包含一个可运行示例的链接供参考。

另一个问题。在Go Playground中,main()函数之上或之前的区域有特定的名称吗?

在Playground中,无论你在main函数上方还是下方定义函数,都没有区别。

例如,这段代码运行正常:

package main

import (
	"fmt"
)

func doSomethingElse() {
	fmt.Println("Doing Something Else!");
}

func main() {
	doSomething()
	doSomethingElse()
}

func doSomething() {
	fmt.Println("Doing Something!")
}

Go Playground - The Go Programming Language

希望这对你有帮助。

嗨 Cherolyn,

抱歉!我刚刚才看到这个。

在我阅读上面的回复之前,由于时间有限,我对老师的解决方案有个疑问。老师说这个…

如你所说,以下代码将返回 xi 切片中的第一个元素加上切片中的最后一个元素。作为参考,这是示例中使用的切片 []int{1, 2, 3, 4, 5, 6}

return xi[0] + xi[len(xi)-1] // 1 + 6

所以,如果你想访问切片中的某个元素,可以使用对应的索引。例如,如果你想获取 xi 切片的第一个元素,你可以这样做:xi[0],记住切片是从 0 开始索引的,所以 0 是第一个元素,1 是第二个元素,依此类推…

返回语句的第一部分 xi[0] 将等于 1,因为在上面的切片中我们可以看到第一个元素是数字 1

然后是一个 + 符号,这实际上是加法运算,因为我们处理的是整数切片。紧接着是这个:

xi[len(xi) - 1]

这可能看起来有点奇怪,但可以分解一下。就像我们获取切片第一个元素时一样,我们只是请求一个特定的索引,在这种情况下,就是 len(xi) - 1 计算出的值。

len 函数负责返回给定切片的长度。例如,如果我们在 xi 切片上调用 len,我们会得到 6,正如预期的那样,因为切片中有 6 个整数。然而,正如我之前提到的,切片索引从 0 开始,所以如果我们执行 xi[6],实际上会得到一个错误,因为切片的索引实际上是 0-5,而不是 1-6。这就是为什么我们要从 len(xi) 返回的值中减去 1。

所以,理论上 xi[len(xi) - 1] 实际上执行的是 xi[5],但我们使用 len 来确定切片中的最后一个元素是什么,因为切片的长度是动态的,可能会改变。

你的代码很好地展示了在Go语言中将函数作为参数传递的概念,这是一个正确的回调函数应用。我来逐一解答你的问题:

问题一:你的想法是否符合要求?

完全符合! 你的代码正确地展示了回调函数的核心概念 - 将一个函数作为参数传递给另一个函数。这正是练习要求的内容。

问题二:代码分析

你的代码基本正确,但有一个小问题需要修复:

package main

import "fmt"

func add42(n int) int {
    return n + 42
}

func main() {
    numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    
    // 这里需要传递函数引用,而不是调用函数
    result := applyFunction(numbers, add42) // 去掉括号,传递函数本身
    
    fmt.Println(result)
}

func applyFunction(nums []int, f func(int) int) []int {
    result := make([]int, len(nums))
    for i, num := range nums {
        result[i] = f(num) // 这里才调用函数
    }
    return result
}

关键区别:

  • applyFunction(numbers, add42) - 正确,传递函数引用
  • applyFunction(numbers, add42()) - 错误,传递的是函数调用的结果

问题三:完整的回调函数示例

这里是一个更完整的例子,展示多种回调函数的应用:

package main

import "fmt"

// 你的原始想法 - 加42
func add42(n int) int {
    return n + 42
}

// 其他可能的回调函数
func double(n int) int {
    return n * 2
}

func square(n int) int {
    return n * n
}

// 通用的应用函数
func applyFunction(nums []int, f func(int) int) []int {
    result := make([]int, len(nums))
    for i, num := range nums {
        result[i] = f(num)
    }
    return result
}

func main() {
    numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    
    fmt.Println("原始数组:", numbers)
    fmt.Println("加42:", applyFunction(numbers, add42))
    fmt.Println("加倍:", applyFunction(numbers, double))
    fmt.Println("平方:", applyFunction(numbers, square))
    
    // 使用匿名函数作为回调
    fmt.Println("加100:", applyFunction(numbers, func(n int) int {
        return n + 100
    }))
}

输出结果:

原始数组: [1 2 3 4 5 6 7 8 9]
加42: [43 44 45 46 47 48 49 50 51]
加倍: [2 4 6 8 10 12 14 16 18]
平方: [1 4 9 16 25 36 49 64 81]
加100: [101 102 103 104 105 106 107 108 109]

你的学习态度很好,继续坚持!回调函数是Go语言中非常重要的概念,广泛应用于排序、过滤、映射等场景。

回到顶部