GO 语言的函数??
函数是什么?
学过编程的 xdm 对于函数自然不会陌生,那么函数是什么呢?
函数是一段可以重用的代码块,可以被多次调用,我们可以通过使用函数,提高咱们代码代码的模块化,提高程序的可读性和可维护性
对 GO 语言中的函数,入参可以有多个,返回值也可以有多个,此处建议,入参不大于 5 个,如果超过 5 个最好使用传入结构的方式来进行处理
程序的初始化顺序?
要了解 GO 语言中程序的初始化顺序,就要先明白整个程序初始化流程中,都会涉及到哪一些内容
GO 语言中以包 package 作为 程序逻辑封装的基本单元,每一个包我们可以理解为他是独立的,封装良好的,并且对外暴露了接口的基本单元
然而,咱们的 GO 程序就是由这些包组成的,那么这个包里面一般又包含着 基本的常量,变量,函数,类型,方法,和接口等等
那么对于上述这些元素,我们就要弄明白在包里面他们是如何有序的进行初始化的
本章主要分享函数,GO 语言中除了 main 函数,还有一个特殊的函数就是 init 函数
fun init() {// 具体的实现// 具体的初始化
}
这里可以看到init 函数,是没有入参,也没有返回值的函数
init 函数用于在本包中进行初始化和做一些程序初始状态的检查工作,例如我们会把一些单例,数据库句柄,各种连接句柄放到 init 函数中进行初始化,init 函数在整个程序生命周期,只会被调用一次
且这里我们需要注意,一个包里面会有多个 GO 语言源文件,这些源文件中都可以定义 init 函数,但是在程序执行 init 函数时,是一个一个的去执行的,而不是并发的去执行的,那么此处的执行顺序我们就不要去过度依赖,按照我们使用惯例来看,过度依赖 init 函数的执行顺序可能会出现意想不到的问题
所以此处我们就需要注意,如果不同的 init 函数实现中,相互有依赖,那么可能就会导致程序出现我们不期望的结果
那么整个程序的初始化流程和顺序我们要知道是这样子的:
对于一个包而言,初始化顺序如下:
- 包内的包级常量
- 包内的包级变量
- 包内的 init 函数
对于一个程序里面,从 main 函数开始,必然是包含了其他的子包,那么初始化的时候是怎么样的呢?
- 先是初始化子包,若子包里面还有子包,那么就继续从最深一层的子包开始按照包里面的初始化顺序进行
- 最深一层的子包按照顺序初始化完毕之后,就到了他的父级包开始按照顺序初始化
- 走到 main 包中的 包级常量,包级变量, init 函数进行初始化
- 最终,执行 main 函数
通过上图是不是对于 GO 程序初始化顺序更加清晰了呢,如果有表述不当的地方,还请多多评论留言,多多指教
我们可以写一个 demo 来看看效果:
demo 的目录结构如下
main.go 文件的内容如下:
package mainimport "fmt"
import _ "ttt/p1"
import _ "ttt/p2"var (_ = checkConst()c = varInit(4)d = varInit(5)
)const (a = 2b = 3
)func init() {fmt.Println("main : init")}func checkConst() int {if a == 2 {fmt.Println("main : const a")}if b == 3 {fmt.Println("main : const b")}return 0
}func varInit(x int) int {fmt.Println("main : var ", x)return x
}func main() {fmt.Println("main : main ")
}
- main 包中,我们导入了 p1 和 p2 包,main 包中定义了 const 常量和变量,以及 对应的 init 函数
- p1 和 p2 包的内容和 main 的大体一直
运行程序之后,我们可以看到打印的结果如下, 通过这个 demo 我们就可以看到程序的初始化顺序正如上所述
p1 : const a
p1 : const b
p1 : var 4
p1 : var 5
p1 : init
p2 : const a
p2 : const b
p2 : var 4
p2 : var 5
p2 : init
main : const a
main : const b
main : var 4
main : var 5
main : init
main : main
具体的 demo 仓库可以查看如下地址:
GO 语言程序初始化顺序 demo
函数在 GO 语言中的地位?
在 GO 中,我们可以看到没有那些高级语言面向对象的语法,例如 Class 类,继承,对象等等内容, GO 语言中可以通过函数或者方法的方式进行各种组合完成我们想做的一切事项
此处就体现了函数在 GO 语言中是极其的重要,函数在 GO 语言中是 一等公民 的存在。
如何体现 一等公民呢?函数在 GO 中可以像普通类型的值一样被创建和被使用,使用起来非常灵活和自由
例如,创建的函数可以存储在变量中,也可以做为其他函数的返回值(在函数内部创建了函数变量之后,通过返回值返回),还可以作为其他函数的参数进行传递
那么我们就来写一些 demo 查看这个 一等公民 是有多么的自由吧:
- 正常写一个 函数,简单实现
func helloworld() string{name := "阿兵云原生"return name
}
- 函数作为入参
func add(a, b int) int {return a + b
}func cal(a int, f func(int, int) int) int {return a + f(a, a)
}
- 函数作为返回值返回出去
func add(a, b int) int {return a + b
}func getFunc() func(int, int) int{return add
}
- 将函数存储在变量中使用
type TestFunc struct {f func(int, int) intname string
}func add(a, b int) int {return a + b
}func main() {tt := &TestFunc{f: add, name: "阿兵云原生"}fmt.Println(tt.f(1,2))}
- 函数作为类型来使用
type PFunc func(int) int
综上所述,对于使用 GO 语言中的函数还是相当方便的,用起来是相当的顺手
那么对于普通类型的数据,我们可以进行显示的类型转换,那么对于函数是不是也可以??
自然是可以的,我们可以来看一个 一般类型的 demo:
var x int = 10
var y int32 = 20
fmt.Println(x + y)
上述代码很明显 x 的类型和 y 的类型是不同的, GO 语言是不会编译通过的,我们需要将其中一个变量的类型显示的转换才可,例如 fmt.Println(int32(x) + t)
再来看看显示转换函数的 demo:
- 写一个 Processer 接口,有一个
Do(int) int
接口 - 定义一个 PFunc 类型对应
func(int) int
- 写一个普通函数和
func playfootball(x int) int
- 在 main 函数中,我们直接将 playfootball 赋值给 Processer 看看效果
type Processer interface {Do(int) int
}type PFunc func(int) intfunc (f PFunc) Do(x int) int {return f(x)
}func playfootball(x int) int {return x
}func main() {var i Processer = playfootballfmt.Println(i.Do(20))
}
运行上述代码,很明显是编译不过的,因为 playfootball 的类型和并没有实现 Do 接口,虽然入参和返回值的类型和个数都一样
我们只需要将上述代码,将 playfootball 显示转换,写成 PFunc(playfootball)
即可顺利通过编译,正常看到打印
因为上述 PFunc 类型实现了 Processer 接口,因此对于 i 需要接收的是 PFunc 的实例,这个时候对 playfootball 进行显示转换后,实际上最终调用的函数 playfootball 函数
GO 语言中的 defer
使用过 GO 语言的 xdm 对于 defer 不会陌生,对于那些我们需要在函数退出前释放或者需要关闭的资源,我们就可以使用到 defer 这里用起来就相当的省心,哪怕函数中出现了 panic,defer 也能给你守护的明明白白的
func test() {defer func() {if e := recover(); e != nil {fmt.Println(e)fmt.Println("recover ... ")}}()panic("panic ...")
}func main() {test()
}
例如上述 demo ,会正常输出,不会 panic ,因为已经被捕获和处理了
使用 defer 能大大的减少我们的开发人员的心智负担,例如我们以前在使用锁的时候,加锁之后,我们可能会忘记写解锁的语句,可使用了 defer ,你完全可以是在加锁的时候,使用 defer 让函数关闭的时候解锁即可,当然具体逻辑还是要看具体的实现
关于 defer 的原理,以及使用 defer 的注意事项就不在过多赘述,可以查看如下文章获得答案
- GO 中的 defer 有哪些注意事项?下
- GO 中的 defer 有哪些注意事项?上
- GO 中 defer的实现原理
总结:
本次分享了函数相关的基本知识,以及 GO 程序的初始化顺序,对于 defer 的使用有想法的欢迎点击上述连接查看具体 defer 的分享细节
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~
可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI
相关文章:

GO 语言的函数??
函数是什么? 学过编程的 xdm 对于函数自然不会陌生,那么函数是什么呢? 函数是一段可以重用的代码块,可以被多次调用,我们可以通过使用函数,提高咱们代码代码的模块化,提高程序的可读性和可维护…...

机器学习基础之《回归与聚类算法(3)—线性回归优化:岭回归》
一、什么是岭回归 其实岭回归就是带L2正则化的线性回归 岭回归,其实也是一种线性回归。只不过在算法建立回归方程时候,加上L2正则化的限制,从而达到解决过拟合的效果 二、API 1、sklearn.linear_model.Ridge(alpha1.0, fit_interceptTrue…...

DirectX3D 正交投影学习记录
所谓正交投影变换,就是已知盒状可视空间内任意点坐标(x,y,z),求解垂直投影到xy平面的对应点坐标。 按照这个定义,xyz坐标系本身就是正交坐标系,盒状可视空间内任意点的坐标(x,y,z)投影到(x,y)平面,只要简单地丢弃z坐标…...

数据挖掘十大算法--Apriori算法
一、Apriori 算法概述 Apriori 算法是一种用于关联规则挖掘的经典算法。它用于在大规模数据集中发现频繁项集,进而生成关联规则。关联规则揭示了数据集中项之间的关联关系,常被用于市场篮分析、推荐系统等应用。 以下是 Apriori 算法的基本概述&#x…...
[蓝桥杯 2022 省 B] 统计子矩阵
题目描述 给定一个 NM 的矩阵 A,请你统计有多少个子矩阵 (最小 11, 最大 NM) 满足子矩阵中所有数的和不超过给定的整数 K。 输入格式 第一行包含三个整数 N, M和 K。 之后 N 行每行包含 M 个整数, 代表矩阵 A。 输出格式 一个整数代表答案。 输入输出样例 输入 #1 3…...
解决在部署springboot项目的docker中执行备份与之相连接的mysql容器命令
文章目录 问题描述解决思路问题解决容器构建mysql客户端安装容器与主机的交互docker中执行 mysqldump 命令解决mysql8密码验证问题解决密码插件警告 问题描述 由于,使用1panel可视化的面板来部署springboot项目,可以很方便地安装和使用mysql,…...
正文Delphi XE Android下让TMemo不自动弹出键盘
用TMemo来显示一段说明文字,可一点Memo,就弹出键盘,找了半天控制键盘的属性,没找到。最后将readOnly设置为True搞定。 如果需要一个form都不显示keyboard,那么可以利用全局变量 VKAutoShowMode来控制,这个全局变量可以有下面三个值…...

[1Panel]开源,现代化,新一代的 Linux 服务器运维管理面板
测评介绍 本期测评试用一下1Panel这款面板。1Panel是国内飞致云旗下开源产品。整个界面简洁清爽,后端使用GO开发,前端使用VUE的Element-Plus作为UI框架,整个面板的管理都是基于docker的,想法很先进。官方还提供了视频的使用教程&…...

PG集合查询
1.运算符 1.1 union并集 连接上下语句 union distinct连接并且去重 all不去重 1.2 intersect交集 上下交集 distinct连接并且去重 all不去重 1.3 except除外 上面除了下面 distinc去重 all不去重...

目标检测应用场景和发展趋势
参考: 目标检测的未来是什么? - 知乎 (zhihu.com)https://www.zhihu.com/question/394900756/answer/32489649815大应用场景 1 行人检测: 遮挡问题:行人之间的互动和遮挡是非常常见的,这给行人检测带来了挑战。非刚性…...

Confluence 自定义博文列表
1. 概述 Confluence 自有博文列表无法实现列表自定义功能,实现该需求可采用页面中引用博文宏标签控制的方式 2. 实现方式 功能入口: Confluence →指定空间→创建页面 功能说明: (1)页面引用博文宏 (…...
chrome历史版本下载
chrome历史版本下载 windows Google Chrome all versions on Windows linux版本 Google Chrome 64bit Linux版_chrome浏览器,chrome插件,谷歌浏览器下载,谈笑有鸿儒...

Messari发布Moonbeam简报,每日交易量稳步增长,首次公布利润数据
区块链数据公司Messari首次发布Moonbeam项目分析简报,从项目市值、链上数据表现、质押以及Moonbeam的技术优势XCM使用量等角度全面分析。这个再熊市初期上线的项目一直在默默开发,并在跨链互操作领域拥有了相当的实操成绩。我们翻译了Messari简报中的部分…...
数据库 锁、索引、在实际开发中怎么设置和优化
数据库锁和索引是数据库管理的两个重要方面,它们对于确保数据的一致性和提高查询性能具有重要作用。在实际开发中,正确地设置和优化锁和索引对于构建高效、稳定的系统至关重要。下面是一些关于如何在实际开发中设置和优化锁和索引的建议: 锁…...

超详细彻底卸载Anaconda详细教程
一、在开始处打开Anaconda Prompt 二、打开后,输入conda install tqdm -f命令并按回车键 conda install tqdm -f三、之后页面会出现一个WANNING,这个我们不用在意,然后会出现一个y/n提示框,在这里我们输入y或者Y y四、输入cond…...

Python--随机出拳(random)--if判断--综合案例练习:石头剪刀布
注:涉及相关链接: Python:if判断--综合案例练习:石头剪刀布-CSDN博客 Python语言非常的强大,强大之处就在于其拥有很多模块(module),这些模块中拥有很多别人已经开发好的代码&…...

微信小程序里配置less
介绍 在微信小程序里,样式文件的后缀名都是wxss,这导致一个问题,就是页面样式过多的时候,要写很多的类名来包裹,加大了工作量,还很有可能会写错样式。这时可以配置一个less,会大大提高代码编辑…...

MySq修改配置文件
要修改 MySQL 的配置文件,您可以按照以下步骤进行操作: 1、打开 MySQL 的配置文件 在大多数 Linux 系统上,默认的配置文件路径是 /etc/my.cnf 或 /etc/mysql/my.cnf。您可以使用文本编辑器(如 vim、nano)以管理员权限打开该文件。 sudo vim /etc/my.cnf 2、进行修改 …...

HTML 表格及练习
表格 概述 表格是一种二维结构,横行纵列。 由单元格组成。 表格是一种非常“强” 的结构: 每一行有相同的列数(单元格),每一列有相同的行数(单元格) 同一列的单元格,宽度&#…...

YOLOv5-训练自己的VOC格式数据集(VOC、自建数据集)
YOLOv5:训练自己的 VOC 格式数据集 1. 自定义数据集 1.1 环境安装 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple注意: 安装 lxmlPillow 版本要低于 10.0.0,解释链接: module ‘PIL.Image’ has no attri…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...