当前位置: 首页 > news >正文

Go语言程序设计-第5章--函数

Go语言程序设计-第5章–函数

5.1 函数声明

每个函数声明都包含一个名字、一个形参列表、一个可选的返回列表以及函数体:

func name(parameter-list) (result-list) {body
}
func add(x int, y int) int { return x + y}
func sub(x, y int) (z int) {z = x - y; return}
func first(x int, _ int) int { return x }
func zero(int, int) int {return 0}fmt.Printf("%T\n", add) // "func(int, int) int"
fmt.Printf("%T\n", sub) // "func(int, int) int"
fmt.Printf("%T\n", add) // "func(int, int) int"
fmt.Printf("%T\n", zero) // "func(int, int) int"

函数的类型称为函数签名

实参是按值传递的。如果提供的实参包含引用类型,比如指针、slice、map、函数或者通道,那么当函数使用形参变量时就有可能间接地修改实参变量。

有些函数的声明没有函数体,说明这个函数使用除了 Go 以外的语言实现。

package math

func Sin(x float64) float64 // 使用汇编语言实现

5.2 递归

5.3 多返回值

函数可以有多个返回值。一个函数如果有命名的返回值,可以省略 return 语句的操作数,称为裸返回

5.4 错误

Go 程序使用通常的控制流机制(比如if 和 return语句)应对错误。

5.4.1 错误处理策略

5.4.2 文件结束标识

EOF 定义:

package io
import "errors"var EOF = errors.New("EOF")

使用示例:

in := bufio.NewReader(os.Stdin)
for {r, _, err := in.ReadRune()if err == io.EOF {break // 结束读取}if err != nil {return fmt.Errorf("read failed: %v", err)}
}

5.5 函数变量

函数变量也有类型,可以赋给变量或者传递给其他函数,或者从其他函数中返回。

func square(n int) int { return n * n }
func negative(n int) int { return  -n }
func product(m, n int) int {return m * n}f = square
mt.Println(f(3)) // "9"

函数类型的零值是nil(空值),调用一个空的函数变量导致宕机。

5.6 匿名函数

strings.Map(func(r rune) rune) {return r + 1}, "HAL-9000")

函数里可以使用外层函数的变量。这些隐藏的变量引用就是我们把函数归类为引用类型而且函数变量无法进行比较的原因。函数变量类似于使用闭包方法实现的变量,Go 程序员通常把函数变量成为闭包。

func squares() func() int {var x intreturn func() int {x++return x * x}
}
func main() {f := squares()fmt.Println(f())fmt.Println(f())fmt.Println(f())fmt.Println(f())
}

输出:

1
4
9
16

警告:捕获迭代变量

var rmdirs []func()
for _, d := range tempDirs() {dir := d // 注意,这一行是必须的os.MkdirAll(dirkk, 0755)rmdirs = append(rmdirs, func() {os.RemoveAll(dir)})
}for _, rmdir := range rmdirs {rmdir() // 清理
}

为什么在循环体内将循环变量赋给一个新的局部变量 dir,而不是下面的版本。

var rmdirs []func()
for _, d := range tempDirs() {os.MkdirAll(dirkk, 0755)rmdirs = append(rmdirs, func() {os.RemoveAll(dir)})
}

原因是循环变量的作用域的规则限制。在上面的程序中,dir 在 for 循环引进的一个块作用域内进行声明。在循环里创建的所有函数变量共享相同的变量 – 一个可以访问的存储位置,而不是固定的值。dir 变量的值在不断地迭代中更新,因为当调用清理函数时,dir 变量是最后一次迭代时的值。我们用内部变量解决这个问题。

for _, dir := range tempDirs() {dir := dir // 声明内部 dir,并以外表 dir 初始化
}

5.7 变长函数(有可变的参数个数)

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

变长函数的类型和一个带有普通 slice 参数的函数类型不相同。

5.8 延迟函数调用

package ioutilfunc ReadFile(filename string)([]byte, error) {f, err := os.Open(filename)if err != nil {return nil, err}defer f.Closereturn ReadAll(f)
}

defer 语句,无论在正常的情况下,执行 return 语句或者函数执行完毕,还是在不正常的情况下,比如发生宕机,实际的调用推迟到包含 defer 语句的函数结束后才放行。

func bigSlowOperation() {defer traxce("bigSlowOperation")() // 别忘记这对圆括号time.Sleep(10 * time.Second)
}func trace(msg string) func() {start := time.Now()log.Printf("enter %s", msg)return func() { log.Printf("exit %s (%s)", msg, time.Since(start))}
}

延迟的匿名函数能够改变外层函数返给调用者的结果。

func triple(x int) (result int) {defer func() { result += x }()return x + x
}func main() {fmt.Println(triple(4))
}

5.9 宕机(Panic)

有些错误(比如数组越界访问或者解引用空指针)都需要在运行时进行检查。当 Go 语言运行时检测到这些错误,就会发生宕机。

一个典型的宕机发生时,正常的程序执行会终止, goroutine 中所有的延迟函数会执行,然后程序会异常退出并打印一条日志。日志消息包括宕机的值,这往往代表某种错误消息,每一个 goroutine 都会在宕机的时候显示一个函数调用的栈跟踪消息。

宕机发生时,defer 函数会以倒序执行。

func main() {defer printStack()
}func printStack() {var buf [4096]byten := runtime.Stack(buf[:], false)os.Stdout.Write(buf[:n])
}

5.10 恢复

recover 会终止当前的宕机状态,并且返回宕机的值。函数不会从之前宕机的地方继续运行而是正常返回。如果 recover 在没有宕机的情况下调用,没有任何结果,并且返回 nil。

相关文章:

Go语言程序设计-第5章--函数

Go语言程序设计-第5章–函数 5.1 函数声明 每个函数声明都包含一个名字、一个形参列表、一个可选的返回列表以及函数体: func name(parameter-list) (result-list) {body }func add(x int, y int) int { return x y} func sub(x, y int) (z int) {z x - y; return} func f…...

数据被锁?被.mkp 勒索病毒攻击后的拯救行动

导言: 网络安全面临着越来越多的挑战,而.mallox勒索病毒则成为数字威胁中的一股强大势力。它的威胁不仅体现在其高度复杂的加密算法上,还表现在对受感染系统的深度渗透和数据的极大破坏上。以下是.mallox勒索病毒的主要威胁:如不…...

Fine-Tuning Language Models from Human Preferences

Abstract 奖励学习(reward learning)可以将强化学习(RL)应用到由人类判断定义奖励的任务中,通过询问人类问题来构建奖励模型。奖励学习的大部分工作使用了模拟环境,但是关于价值的复杂信息经常是以自然语言的形式表达的。我们相信语言奖励学习是使强化学习在现实世界任务…...

提升数据库性能的关键指南-Oracle AWR报告

文章目录 一、了解AWR报告:数据库性能的仪表盘二、生成AWR报告三、解读AWR报告的关键部分1.报告开头的系统基础信息2.ADDM发现3.负载概览(Load Profile)4.参数文件5.顶级前台等待事件6.SQL 统计信息-顶级SQL7.SGA Advisory AND PAG Advisory 一、了解AWR报告&#x…...

云计算IaaS、PaaS和SaaS之

提供的服务来比较如下两图 示例图 示例图...

解锁大数据世界的钥匙——Hadoop HDFS安装与使用指南

目录 1、前言 2、Hadoop HDFS简介 3、Hadoop HDFS安装与配置 4、Hadoop HDFS使用 5、结语 1、前言 大数据存储与处理是当今数据科学领域中最重要的任务之一。随着互联网的迅速发展和数据量的爆炸性增长,传统的数据存储和处理方式已经无法满足日益增长的需求。…...

写在2023岁末:敏锐地审视量子计算的当下

本周,《IEEE Spectrum》刊登了一篇出色的文章,对量子计算(QC)的近期前景进行了深入探讨。 文章的目的并不是要给量子计算的前景泼冷水,而是要说明量子计算的前景还很遥远,并提醒读者量子计算的用例可能很窄…...

C/C++学习笔记十三 C++中的重载运算符

1、什么是运算符重载? 运算符重载是 C 中的一项功能,使运算符(例如 、- 等)能够处理用户定义的数据类型。这种机制称为编译时多态性,并提供了为不同数据类型定制运算符行为的优点。 例如,我们可以重载“”运…...

Java 实现自动获取法定节假日

一、背景 在实现业务需求的过程中,遇到了需要计算 x 个工作日后的日期需求。由于工作日是每年国务院发布的,调休和休假都没有规律,所以无法使用算法进行计算。 一般的实现方案是自己维护一个工作日和调休的表,或者去爬取国务院发…...

湘潭大学-2023年下学期-c语言-作业0x0a-综合1

A 求最小公倍数 #include<stdio.h>int gcd(int a,int b) {return b>0?gcd(b,a%b):a; }int main() {int a,b;while(~scanf("%d%d",&a,&b)){if(a0&&b0) break;printf("%d\n",a*b/gcd(a,b));}return 0; }记住最大公约数的函数&…...

网络协议-BIO实战和NIO编程

网络通信编程基本常识 在开发过程中&#xff0c;如果类的名字有 Server 或者 ServerSocket 的&#xff0c;表示这个类是给服务端容纳网络 服务用的&#xff0c;如果类的名字只包含 Socket 的&#xff0c;那么表示这是负责具体的网络读写的。 ServerSocket 并不负责具体的网络读…...

Word 将页面方向更改为横向或纵向

文章目录 更改整个文档的方向更改部分页面的方向方法1&#xff1a;方法2&#xff1a; 参考链接 更改整个文档的方向 选择“布局”>“方向”&#xff0c;选择“纵向”或“横向”。 更改部分页面的方向 需要达到下图结果&#xff1a; 方法1&#xff1a; 选:中你要在横向页面…...

关键字:abstract关键字

在 Java 中&#xff0c;abstract是一个关键字&#xff0c;用于修饰类和方法。当一个类被声明为抽象类时&#xff0c;它不能被实例化&#xff0c;只能被其他类继承。同时&#xff0c;抽象类可以包含抽象方法&#xff0c;抽象方法没有方法体&#xff0c;只包含方法的签名&#xf…...

从PDF中提取图片

由于工作需要&#xff0c;要从pdf文件中提取出图片保存到本地&#xff0c;项目中就引用到了Apache PDFBox库。 1 什么是Apache PDFBox? Apache PDFBox库&#xff0c;一个用于处理PDF文档的开源Java工具。它允许用户创建全新的PDF文件&#xff0c;操作现有的PDF文档&#xff0…...

推荐:一个不错的介绍Apache Doris的PPT

原来Apache Doris居然是百度开源出来的&#xff0c;不错。部分节选&#xff1a;完整下载地址网盘&#xff1a; 链接: https://pan.baidu.com/s/18WR70R_f72GxCjh0lykStQ 提取码: umd3 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 --来自百度网盘超级会员v7的分…...

【Python_PySide2学习笔记(二十二)】进度对话框QProgressDialog类的基本用法

进度对话框QProgressDialog类的基本用法 进度对话框QProgressDialog类的基本用法前言一、QProgressDialog 的常用方法1、创建进度对话框2、进度对话框设置窗口标题3、进度对话框隐藏"最大化"、"最小化"、"关闭"4、进度对话框设置是否自动关闭5、…...

使用rust读取usb设备ACR122U的nfc卡片id

rust及其高效和安全著称&#xff0c;而且支持跨平台&#xff0c;所以就想使用这个rust开发一个桌面端程序&#xff0c;来读取nfc设备的nfc卡片的id信息&#xff0c;下面就做一个最简单的入门教程吧&#xff0c;也是我写的第三个rust应用。 当你电脑上安装好了rust环境之后&…...

servlet总结

目录 1.生命周期 2.线程总结 3.配置 4.请求和响应 5.会话管理 6.过滤和监听器 7.处理表单数据 8.与JSP集成 9.异常处理 10.安全性和认证 Servlet是一种基于Java的Web组件&#xff0c;用于处理客户端请求并生成动态Web内容。以下是关于Servlet的一些总结 1.生命周期 …...

Nacos2.1.2改造适配达梦数据库7.0

出于业务需求&#xff0c;现将Nacos改造适配达梦数据库7.0&#xff0c;记录本次改造过程。 文章目录 一、前期准备二、适配流程1、项目初始化2、引入驱动3、源码修改 三、启动测试四、打包测试 一、前期准备 Nacos源码&#xff0c;版本&#xff1a;2.1.2&#xff1a;源码下载…...

TPRI-DMP平台介绍

TPRI-DMP平台介绍 1 TPRI-DMP平台概述 TPRI-DMP为华能集团西安热工院自主产权的工业云PaaS平台&#xff0c;已经过13年的发展和迭代&#xff0c;其具备大规模能源电力行业生产应用软件开发和运行能力。提供TPRI-DMP平台主数据管理、业务系统开发与运行、应用资源管理…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...