本文首发于公众号:Hunter后端

原文链接:Golang基础笔记八之函数

本篇笔记介绍 Golang 里函数相关的内容,以下是本篇笔记目录:

  1. 函数的定义语法
  2. 函数返回值
  3. 可变参数函数
  4. 匿名函数
  5. 闭包

1、函数的定义语法

函数的定义格式如下:

func 函数名(参数列表) (返回值列表) { 函数体 }

比如下面是一个两数相加返回其和的函数:

func add(a, b int) int {
    return a + b
}

调用的话,直接传参调用即可:

sum := add(1, 4)
fmt.Println(sum)

传入的参数可以传值,也可以传指针,如果传指针的话,在函数内部修改后,会影响原值。

以下是一个传指针修改的示例:

func test(a *int, b int) {
    *a += 2
    b += 2
}
func main() {
    a := 1
    b := 1
    fmt.Printf("调用前 a:%d, b:%d\n", a, b)
    test(&a, b)
    fmt.Printf("调用后 a:%d, b:%d\n", a, b)
}

输出结果为:

调用前 a:1, b:1
调用后 a:3, b:1

2、函数返回值

函数返回值可以返回单个或多个,在函数定义的时候指定返回类型即可:

func add(a, b int) int {
    return a + b
}
func swap(a, b int) (int, int) {
    return b, a
}

还可以对返回值命名,就是在定义函数的时候,将返回值提前声明定义,然后在函数内部对其赋值,函数末尾可以省去 return 具体变量的操作。

比如下面:

func calc(a, b int) (sum, sub int) {
    sum = a + b
    sub = a - b
    return
}

3、可变参数函数

可变参数函数可以接受任意数量的参数,在函数定义的时候,类型前面加上 ... 即表示该参数是可变参数,而在函数内部,可将其作为切片使用。

下面是一个示例,可以接受任意多个元素,作为求和函数的参数:

func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

调用的时候,可以直接传入任意数量参数:

sum(1, 2, 3, 4)

也可以传入一个切片:

slice := []int{1, 2, 3}
s2 := sum(slice...)

4、匿名函数

匿名函数通常用于临时需要处理某个功能,或需要将其作为参数传递给其他变量的场景。

比如下面定义并立即调用了匿名函数:

total := func(a, b int) int {
    return a + b
}(2, 4)

也可以将其赋值给某个变量,再由该变量来调用:

sumFunc := func(a, b int) int {
    return a + b
}
sumFunc(1, 2)

5、闭包

闭包是指能够读取其他函数内部变量的函数,即使该函数已经执行完毕,其作用域内的变量也不会被销毁。

我们可以使用闭包来捕获外部函数的局部变量,并将其生命周期延长至闭包本身,比如实现一个计数器:

func counter() func() int {
count := 0
return func() int {
count += 1
return count
}
} counterFunc := counter()
fmt.Println(counterFunc())
fmt.Println(counterFunc())
fmt.Println(counterFunc())
fmt.Println(counterFunc())

也可以根据外部传入的参数生成不同的闭包实例,比如实现一个计算器:

func calculate(calculate_type string) func(a, b int) int {
if calculate_type == "add" {
return func(a, b int) int {
return a + b
}
} else if calculate_type == "sub" {
return func(a, b int) int {
return a - b
}
} else {
return func(a, b int) int { return a + b }
}
} addFunc := calculate("add")
fmt.Println(addFunc(10, 5)) subFunc := calculate("sub")
fmt.Println(subFunc(3, 1))

而闭包也可以维护迭代的状态,因此可以实现迭代器的功能,比如实现一个斐波那契数列生成器:

func fibonacci() func() int {
a, b := 0, 1
return func() int {
f_count := a
a, b = b, a+b
return f_count
}
} f := fibonacci()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())

Golang基础笔记八之函数的更多相关文章

  1. Golang基础笔记

    <基础> Go语言中的3个关键字用于标准的错误处理流程: defer,panic,recover. 定义一个名为f 的匿名函数: Go 不支持继承和重载. Go的goroutine概念:使 ...

  2. TensorFlow基础笔记(11) conv2D函数

    #链接:http://www.jianshu.com/p/a70c1d931395 import tensorflow as tf import tensorflow.contrib.slim as ...

  3. Py修行路 python基础 (八)函数(随时更改)

    为何要用函数: 1.解决代码重用的问题 2.提高代码的可维护性,统一维护 3.程序的组织结构清晰,可读性强 定义函数 先定义后使用!!! def funcname(arg1,arg2,.....)  ...

  4. golang 基础 map及工厂函数

    Map是一种数据结构,是一个集合,用于存储一系列无序的键值对.它基于键存储的,键就像一个索引一样,这也是Map强大的地方,可以快速快速检索数据,键指向与该键关联的值. 内部实现 Map是基于 散列表 ...

  5. TensorFlow基础笔记(11) max_pool2D函数

    # def max_pool2d(inputs, # kernel_size, # stride=2, # padding='VALID', # data_format=DATA_FORMAT_NHW ...

  6. Golang基础之函数

    golang基础之函数 1.为什么需要函数? 有些相同的代码可能出现多次,如果不进行封装,那么多次写入到程序中,会造成程序冗余,并且可读性降低 2.什么是函数 为完成某些特定功能的程序指令集合称为函数 ...

  7. 《MFC游戏开发》笔记八 游戏特效的实现(二):粒子系统

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9360993 作者:七十一雾央 新浪微博:http:// ...

  8. golang学习笔记8 beego参数配置 打包linux命令

    golang学习笔记8 beego参数配置 打包linux命令 参数配置 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/docs/mvc/contro ...

  9. go微服务框架kratos学习笔记八 (kratos的依赖注入)

    目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...

  10. Golang基础教程

    以下使用goland的IDE演示,包含总计的golang基础功能共20个章节 一.go语言结构: 二.go基础语法: 三.变量 四.常量 五.运算符 六.条件语句 七.循环 八.函数 九.变量作用域 ...

随机推荐

  1. 【Python】import模块和包

    模块和包 一. 模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块能定义函数,类和变量,模块里也能包含可执 ...

  2. EntityFrameworkCore 中实体的几种配置方法

    使用数据注解 实体类通常是在Models目录下,直接在实体类上添加属性注解,比如[Required]/[Key]等. using System.ComponentModel.DataAnnotatio ...

  3. C#/.NET/.NET Core技术前沿周刊 | 第 32 期(2025年3.24-3.31)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  4. [设计模式/Java] 设计模式之工厂方法模式【11】

    概述:工厂方法模式 := Factory Method Pattern 工厂模式的3种细分模式: 简单工厂模式 / 工厂方法模式 / 抽象工厂模式 工厂模式(Factory Pattern)是 Jav ...

  5. 通过 C# 获取PDF文档中的字体名、大小、颜色、样式等

    在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响.然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文档.获取PDF中的字体信息可以解决这个问题,让我们能 ...

  6. shell处理字符串

    概念 字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号. 单引号声明字符串 单引号里的任何字符都会原样输出, ...

  7. macOS 和 Windows 操作系统下如何安装和启动 MySQL / Redis 数据库

    你好,我是 Kagol,个人公众号:前端开源星球(欢迎关注我,分享更多前端开源知识). TinyPro 后台管理系统的 NestJS 后端依赖 MySQL 和 Redis 数据库,本文主要带大家安装和 ...

  8. QT 可绑定属性 QProperty QObjectBindableProperty QObjectComputedProperty,简化信号、槽(SIGNAL、SLOT)机制的方法

    QT提供的可绑定属性是指这些属性可以绑定到其他值或表达式上(通常是 C++ lambda 表达式).如果属性是通过表达式进行绑定,该属性会跟随表达式自动更新.可绑定属性由 QProperty 类和 Q ...

  9. python读取文件夹内所有图片名称,随机设置为桌面壁纸且把设置后的图片移到其他文件夹内的方法

    关键词:读取文件夹.读取文件.操作系统.设置壁纸.移动文件 预期实现如下几个步骤 1.获取指定文件夹内所有图片名 2.随机取一张图片设置为壁纸 3.设置为壁纸的图片移动到另外一个文件夹中 第一步,获取 ...

  10. 【BUG】ELF文件执行时出现段错误Segmentation fault,解决:使用010编辑器修改ELF文件不可执行段权限

    问题:段错误,.eh_frame不可执行. 需求:改执行权限. 工具:010 Editer,我的版本:12.0.1 Windows 10. 工具下载:010编辑器官网下载页. 第一步 查看段的执行权限 ...