函数进阶

函数作用域

1.全局变量,在程序整个生命周期都是有效的
2.局部变量:函数内定义/语句块内定义

变量可变性

包内任何变量或者函数都是能访问的。包外的话,首字母大写是可导出的能够被其他包访问或调用。小写表示是私有的,不能被外部的包访问。同一个包内大小写的全局变量或者函数是能被直接调用的。

跨包导入和调用:
  1: 导入:
  2: import (
  3:     github.com\apple_school\listen1\function\calc"
  4: )
  5: 调用:
  6: calc.Add()
  7: calc.A
匿名函数
  1: func add(a, b int) int {
  2:     return a + b
  3: }
  4: func test(){
  5:     f1 := add
  6:     fmt.Printf("type of f1=%T\n", f1)
  7: }
  8: func main() {
  9:     test()
 10: }
  1: func test_1() {
  2:     f1 := func(a, b int) int {
  3:         return a + b
  4:     }
  5:     fmt.Printf("type of f1=%T\n", f1)
  6: }

defer中使用匿名函数,注意下面两种区别

  1: func test_2() {
  2:     var i int = 0
  3:     defer fmt.Printf("i=%d\n", i) // defer里i=0传进去了
  4:     i = 100
  5:     return
  6: }
  7: >>> i = 0
  8:
  9: func test_3() {
 10:     var i int = 0
 11:     defer func() {
 12:         fmt.Printf("defer i=%d\n", i)
 13:     } ()
 14:     i = 100
 15:     return
 16: }
 17: >>> defer i=100

函数作为参数

  1: func add(a, b int) int {
  2:     return a + b
  3: }
  4:
  5: func test_c(a, b int32) int32 {
  6:     return a * b
  7: }
  8:
  9: func sub(a, b int) int {
 10:     return a - b
 11: }
 12:
 13: func calc(a, b int,op func(int, int) int) int {
 14:     return op(a, b)
 15: }
 16:
 17: func test_4() {
 18:     sum := calc(100, 300, add)
 19:     sub := calc(100, 300, sub)
 20:     su := calc(100, 300, test_c)
 21:     fmt.Printf("sum=%d sub=%d\n", sum, sub)
 22: }
 23: 

闭包

即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。

例子1:

  1: package main
  2: import "fmt"
  3:
  4: func add(base int) func(int) int {
  5:     return func(i int) int {
  6:         base += i
  7:         return base
  8:     }
  9: }
 10: func main() {
 11:     tmp1:= add(10)
 12:     fmt.Println(tmp1(1), tmp1(2), tmp1(3))
 13:     tmp2:= add(100)
 14:     fmt.Println(tmp2(1), tmp2(2), tmp2(3))
 15: }
 16: >>> 11 13 16
 17: 101 103 106

例子2:

  1: package main
  2: import (
  3:     "fmt"
  4:     "strings"
  5: )
  6:
  7: func makeSuffix(suffix string) func(string) string {
  8:     return func(name string) string {
  9:         if !strings.HasSuffix(name, suffix) {
 10:             return name + suffix
 11:         }
 12:         return name
 13:     }
 14: }
 15: func main() {
 16:     func1 := makeSuffixFunc(".bmp")
 17:     func2 := makeSuffixFunc(".jpg")
 18:     fmt.Println(func1("test"))
 19:     fmt.Println(func2("test"))
 20: }
 21:
 22: >>> test.bmp
 23: test.jpg

用python3来写就是这样(比较容易理解)

  1: def makeSuffix(suffix):
  2:
  3:     def func(name):
  4:         if  not name.endswith(suffix):
  5:             return name + suffix
  6:     return func
  7: func = makeSuffix(".bmg")
  8: print(func("test"))

例子3:

  1: func calc(base int) (func(int) int, func(int) int) {
  2:     add:= func(i int) int {
  3:         base += i
  4:         return base
  5:     }
  6:     sub:= func(i int) int {
  7:         base -= i
  8:         return base
  9:     }
 10:     return add, sub
 11: }
 12:
 13: func main() {
 14:     f1, f2 := calc(10)
 15:     fmt.Println(f1(1), f2(2))
 16:     fmt.Println(f1(3), f2(4))
 17:     fmt.Println(f1(5), f2(6))
 18:     fmt.Println(f1(7), f2(8))
 19: }
 20:
 21: >>> 11 9
 22: 12 8
 23: 13 7
 24: 14 6

闭包的意义

返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

在多线程下的闭包的副作用:(了解就行了)
  1: package main
  2:
  3: import (
  4:     "fmt"
  5:     "time"
  6: )
  7: func main() {
  8:     for i:=0;i<5;i++ {
  9:         go func(){
 10:             fmt.Println(i)
 11:         } ()
 12:     }
 13:     time.Sleep(time.Second*1)
 14: }

几次的输出结果你会发现不但数值不是固定的,而且居然还会打印出5。本来循环在i=5是就停止了,但是协程搞了鬼,这个后面再讲。

转载于:https://www.cnblogs.com/haoqirui/p/10115103.html

Go语言学习笔记(八)相关推荐

  1. R语言学习笔记(八)--读写文件与网络爬虫

    R语言学习笔记(八) 1 工作路径 2 保存R对象 3 Scan函数 3-1 从控制台读取数据 3-2 从txt文件读取数据 3-3 从url读取数据 4 按行读写文本文件 5 读取文本文件(txt. ...

  2. 计算机二级C语言学习笔记(十八)

    上一篇:计算机二级C语言学习笔记(十七) 程序填空题(二) 题型二:平均值 首先求和,然后将和除以项数 ===================================== ========== ...

  3. ROS学习笔记八:创建ROS msg和srv

    ROS学习笔记八:创建ROS msg和srv 本节主要讲述了如何创建和建立ROS msg和srv,同时使用命令行工具rosmsg.rossrv和roscp. msg和srv简介 msg:描述ROS m ...

  4. 【Go语言 · 学习笔记】

    文章目录 Go语言 · 学习笔记 一.Go包管理 1. 什么是Go语言中的包 2. 包的命名 3. main包 4. 导入包 5. 远程包导入 6. 命名导入 7. 包的init函数 二.Go开发工具 ...

  5. 易语言学习笔记——基础篇

    易语言学习笔记20180710 一. 易语言的数据类型可以分为基本数据类型和特殊数据类型 1.     其中基本数据类型分为: ①   数值型 ②   逻辑型 ③   日期时间型 ④   文本型 ⑤  ...

  6. 易语言学习笔记——命令篇

    易语言学习笔记20180711 一. 命令概述 1.     什么是命令:命令是一个功能调用的开始. 2.     命令的参数:调用一个功能方法时候输入的数据或者条件. 3.     命令的返回值:调 ...

  7. C语言学习笔记Day3——持续更新中... ...

    上一篇文章C语言学习笔记Day2--持续更新中- - 八. 容器 1. 一维数组 1.1 什么是一维数组 当数组中每个元素都只带有一个下标(第一个元素的下标为0, 第二个元素的下标为1, 以此类推)时 ...

  8. 黑马程序员_java自学学习笔记(八)----网络编程

    黑马程序员_java自学学习笔记(八)----网络编程 android培训. java培训.期待与您交流! 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无 ...

  9. OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7888 ...

  10. c语言注释语句执行吗,C语言学习笔记之C语言概念解析(附资料分享)每一个语句都必须以分号结尾但预处理命令函数头和花括号“}”之后不能加分号...

    [[怪兽爱C语言]C语言学习笔记之C语言概念解析(附资料分享)]https://toutiao.com/group/6582429294901854728/?iid=15906422033&a ...

最新文章

  1. 小程序 a标签_微慕WordPress小程序增强版V2.0新版上线
  2. 35. Search Insert Position
  3. 数据结构--双向链表
  4. 钟国晨160809323 (作业9)
  5. java 简单的加法 递归 从A加到B
  6. java设计模式在java中的应用
  7. nbsp;在IE和FIREFOX下位置不对
  8. centos7使用kubeadm部署高可用k8s集群
  9. C语言以科学计数法的格式打印
  10. bmd硬盘测试_Blackmagic Disk Speed Test for Mac(硬盘测速工具)v3.2免费版
  11. 计算机教室的英语单词怎么写,教室的英语单词怎么写
  12. php扩展exif模块,Centos+PHP模块+exif扩展 (第三方模块)
  13. 水泥行业超低排放政策频发,企业如何完成超低排放改造?
  14. 进程间的通信(管道通信)
  15. linux服务器光衰,linux下怎么查看光模块光功率
  16. 支撑软件开发人员的三种精神
  17. unity - 打出的IPA包太大
  18. 石门一中2021年高考成绩查询,石门一中火了!2020年高考成绩再次刷新记录
  19. Jenkins 贡献者线上峰会 - 二月 23 日至 25 日
  20. 计算机软件工程班级简介,热点 | 优秀班集体——2015级软件工程班

热门文章

  1. 「代码随想录」本周学习小结!(动态规划系列三)
  2. 解决苹果mac新建txt文档在Windows下不换行的方法
  3. 在 Mac 上如何使用 iCloud 钥匙串保护信息安全?
  4. 玛雅Maya 2022 for Mac(三维动画制作软件)
  5. MacOS六个常用的终端命令
  6. 如何在前端中使用protobuf(vue篇)
  7. 2017.11.24 Stm8L151-factory
  8. java破解ip屏蔽+多线程同步拨号-【多线程数据采集之五】
  9. 在云上搭建大规模实时数据流处理系统
  10. 诗一首,程序员不仅仅只会写程序