当前位置: 首页 > 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平台主数据管理、业务系统开发与运行、应用资源管理…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...