一道正确率只有15%的命名返回值和闭包的问题

Posted Golang梦工厂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道正确率只有15%的命名返回值和闭包的问题相关的知识,希望对你有一定的参考价值。

声明,编译器会进行类型推断和赋值,已经声明的变量不会重新声明,直接在原变量上赋值;之后我们return的是一个闭包函数,闭包里的done值并不会被提前解析,在bbb()函数结束后,实际对应的代码就成了这样,变成了递归。

done = func() 
  print("bbb: surprise!");
  done()

如果我们把代码在改成这样:

func bbb() (func()error) 
 var done func()
 done, err := aaa()
 return func() 
  print("bbb: surprise!");
  done()
 , err

答案就是【B】:bbb: surprise!aaa: done

总结

一道看似简单的题,其中蕴涵的知识点确有很多,这就说明了解设计原理是多么的重要,Go语言资深工程师的路上任重道远呀~。

好啦,本文到这里就结束了,我是asong,我们下期见。

创建了读者交流群,欢迎各位大佬们踊跃入群,一起学习交流。入群方式:关注公众号获取。更多学习资料请到公众号领取。

Go语言闭包

总的来说,闭包就是一个函数,他的返回值也是一个函数,并且作为返回值的这个函数能够调用之前函数的参数:

// 函数作为返回值和作为返回值的这个函数能够调用之前函数的参数,就是Go语言闭包的精髓
// 可以类比为python中的装饰器
func f1(x int) func() {
	return func() {
		// 返回值就是这个匿名函数
		// 作为返回值的这个函数调用了之前函数的参数x
		fmt.Println(x)
	}
}

举例说明:

  首先有一个函数f1,它的参数是一个不带参数和返回值的函数:

func f1(f func()) {
	fmt.Println("this is in f1")
	f()
}

  然后有一个函数f2,它的参数是两个整型的变量

func f2(x, y int) {
	fmt.Println("this is in f2")
	fmt.Println(x + y)
}

  此时如果我们需要将f2传入f1中执行,就不能直接f1(f2),因为这样会产生类型不匹配的问题。

  所以此时我们构造一个闭包函数f3,他的传入的参数是两个整型变量,这两个变量作为f2的入口参数,然后返回一个没有参数的函数作为返回值,这个返回值就是f1的入口参数

func f3(x, y int) func() {
	fmt.Println("this is in f3")
	retFunc := func() {  //这个就是返回的函数
		f2(x, y)  //在返回的函数中调用之前的函数的参数
	}
	return retFunc
}
func main() {
	f := f3(1, 2)
	f1(f)
}

  此时在main函数中的f的类型为一个不带参数的函数,他就可以作为f1的入口参数了

  输出的结果为:  

          this is in f3
          this is in f1
          this is in f2
          3

  再看另一个例子,对于同一次声明的闭包的变量,他们会共用公有的变量

  首先定义一个函数闭包,他返回两个函数,这两个函数有一个参数一个返回值,分别代表加和减,主函数传入的参数为base,是返回的两个函数的公共变量

func calc(base int) (func(int) int, func(int) int) {
	add := func(x int) int {
		base += x
		return base
	}
	sub := func(x int) int {
		base -= x
		return base
	}
	return add, sub
}

  函数calc中的add和sub的作用就是分别对base进行加和减x

  然后在main函数中使用这个函数闭包

func main() {
	add1, sub1 := calc(10)
	// 因为add1和sub1是同一次初始化的,所以他们共用公共变量base
	// 下面3次运算add和sub都是base=10的基础上一直计算,并且上一次对base更改的值会在下一次运算中生效
	fmt.Println(add1(1), sub1(2)) //11 9
	fmt.Println(add1(3), sub1(4)) //12 8
	fmt.Println(add1(5), sub1(6)) //13 7
	add2, sub2 := calc(20)
	// add2和sub2不是和add1与sub1同一次定义,所以他们不是共用的公共变量
	// 此时是新初始化的公共变量base=20
	fmt.Println(add2(1), sub2(2)) //21 19
	fmt.Println(add2(3), sub2(4)) //22 18
	fmt.Println(add2(5), sub2(6)) //23 17
	// 也就是说闭包会在一定程度上面延长局部变量的生命周期
}

  从上面的代码可以看出,函数闭包延长了函数中的局部变量的生命周期,上面的例子中,被延长的变量就是base。

最后一句话总结Go中的闭包,闭包就是一个函数的返回值是一个函数,并且作为返回值的函数能够调用这个函数中的局部变量,这些局部变量相当于返回函数的外部变量。

以上是关于一道正确率只有15%的命名返回值和闭包的问题的主要内容,如果未能解决你的问题,请参考以下文章

grails 命名查询返回不正确的数据

关于闭包

ICRA 2022杰出论文:把自动驾驶2D图像转成鸟瞰图,模型识别准确率立增15%

ICRA 2022杰出论文:把自动驾驶2D图像转成鸟瞰图,模型识别准确率立增15%

ICRA 2022杰出论文:把自动驾驶2D图像转成鸟瞰图,模型识别准确率立增15%

C++返回的数组值不正确