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

GO 语言的函数??

函数是什么?

学过编程的 xdm 对于函数自然不会陌生,那么函数是什么呢?

函数是一段可以重用的代码块,可以被多次调用,我们可以通过使用函数,提高咱们代码代码的模块化,提高程序的可读性和可维护性

对 GO 语言中的函数,入参可以有多个,返回值也可以有多个,此处建议,入参不大于 5 个,如果超过 5 个最好使用传入结构的方式来进行处理

程序的初始化顺序?

要了解 GO 语言中程序的初始化顺序,就要先明白整个程序初始化流程中,都会涉及到哪一些内容

GO 语言中以包 package 作为 程序逻辑封装的基本单元,每一个包我们可以理解为他是独立的,封装良好的,并且对外暴露了接口的基本单元

然而,咱们的 GO 程序就是由这些包组成的,那么这个包里面一般又包含着 基本的常量,变量,函数,类型,方法,和接口等等

那么对于上述这些元素,我们就要弄明白在包里面他们是如何有序的进行初始化的

本章主要分享函数,GO 语言中除了 main 函数,还有一个特殊的函数就是 init 函数

fun init() {// 具体的实现// 具体的初始化
}

这里可以看到init 函数,是没有入参,也没有返回值的函数

init 函数用于在本包中进行初始化和做一些程序初始状态的检查工作,例如我们会把一些单例,数据库句柄,各种连接句柄放到 init 函数中进行初始化,init 函数在整个程序生命周期,只会被调用一次

且这里我们需要注意,一个包里面会有多个 GO 语言源文件,这些源文件中都可以定义 init 函数,但是在程序执行 init 函数时,是一个一个的去执行的,而不是并发的去执行的,那么此处的执行顺序我们就不要去过度依赖,按照我们使用惯例来看,过度依赖 init 函数的执行顺序可能会出现意想不到的问题

所以此处我们就需要注意,如果不同的 init 函数实现中,相互有依赖,那么可能就会导致程序出现我们不期望的结果

那么整个程序的初始化流程和顺序我们要知道是这样子的:

对于一个包而言,初始化顺序如下

  1. 包内的包级常量
  2. 包内的包级变量
  3. 包内的 init 函数

对于一个程序里面,从 main 函数开始,必然是包含了其他的子包,那么初始化的时候是怎么样的呢?

  1. 先是初始化子包,若子包里面还有子包,那么就继续从最深一层的子包开始按照包里面的初始化顺序进行
  2. 最深一层的子包按照顺序初始化完毕之后,就到了他的父级包开始按照顺序初始化
  3. 走到 main 包中的 包级常量,包级变量, init 函数进行初始化
  4. 最终,执行 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 ")
}
  1. main 包中,我们导入了 p1 和 p2 包,main 包中定义了 const 常量和变量,以及 对应的 init 函数
  2. 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 查看这个 一等公民 是有多么的自由吧:

  1. 正常写一个 函数,简单实现
func helloworld() string{name := "阿兵云原生"return name
}
  1. 函数作为入参
func add(a, b int) int {return a + b
}func cal(a int, f func(int, int) int) int {return a + f(a, a)
}
  1. 函数作为返回值返回出去
func add(a, b int) int {return a + b
}func getFunc() func(int, int) int{return add
}
  1. 将函数存储在变量中使用
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))}
  1. 函数作为类型来使用
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:

  1. 写一个 Processer 接口,有一个 Do(int) int 接口
  2. 定义一个 PFunc 类型对应 func(int) int
  3. 写一个普通函数和 func playfootball(x int) int
  4. 在 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 的注意事项就不在过多赘述,可以查看如下文章获得答案

  1. GO 中的 defer 有哪些注意事项?下
  2. GO 中的 defer 有哪些注意事项?上
  3. 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&#xff0c…...

正文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…...

基于Java的考研信息查询系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding) 代码参考数据库参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…...

Linux性能优化--性能追踪:受CPU限制的应用程序(GIMP)

10.0 概述 本章包含了一个例子:如何用Linux性能工具在受CPU限制的应用程序中寻找并修复性能问题。 阅读本章后,你将能够: 在受CPU限制的应用程序中明确所有的CPU被哪些源代码行使用。用1trace和oprofile弄清楚应用程序调用各种内部与外部函…...

BERT变体(1):ALBERT、RoBERTa、ELECTRA、SpanBERT

Author:龙箬 Computer Application Technology Change the World with Data and Artificial Intelligence ! CSDNweixin_43975035 *天下之大,虽离家万里,何处不可往!何事不可为! 1. ALBERT \qquad ALBERT的英文全称为A Lite versi…...

域控操作二:设置域用户使用简单密码

过程太多简单 直接写出路径更改即可 组策略—计算机配置----策略—Windows设置–安全设置----账户策略–密码策略 按自己想法改就行了 注意一点!!!!! 要么自己设置策略,要么从默认策略改!&am…...

python---三目运算符

在Python中三目运算符也叫三元运算符,其主要作用:就是用于 简化if...else...语句。 基本语法: 原 if 条件判断: # 语句段1 else: # 语句段2 新-----三目运算符/三元运算符 语句段1 if 条件判断 else 语句段2 案例 输入两个数…...

百度地图定位BMap.GeolocationControl的用法

BMap.GeolocationControl 是百度地图API中的一个类,用于添加地理定位控件到地图上,以便用户可以通过该控件获取自己的当前位置。以下是 BMap.GeolocationControl 的用法示例: 首先,确保已经加载了百度地图API,并且创建…...

Vue3响应式原理初探

vue3响应式原理初探 为什么要使用proxy取代defineProperty使用proxy如何完成依赖收集呢? 为什么要使用proxy取代defineProperty 原因1:defineproperty无法检测到原本不存在的属性。打个🌰 new Vue({data(){return {name:wxs,age:25}}})在vue…...

firewalld常用的基础配置

firewalld防火墙是centos7系统默认的防火墙管理工具,取代了之前的iptables防火墙,也是工作在网络层,属于包过滤防火墙。 支持IPv4、IPv6防火墙设置以及以太网桥支持服务或应用程序直接添加防火墙规则接口拥有两种配置模式:临时模…...

功率放大器如何驱动超声波换能器

驱动超声波换能器的功率放大器在超声波应用中起着至关重要的作用。它能够提供足够的功率和精确的信号控制,使换能器能够有效地将电能转换为超声波能量。下面安泰电子将介绍功率放大器如何驱动超声波换能器的原理和关键要点。 首先,让我们了解一下超声波换…...

LiveGBS流媒体平台GB/T28181常见问题-安全控制HTTP接口鉴权勾选流地址鉴权后401Unauthorized如何播放调用接口

LiveGBS流媒体平台GB/T28181常见问题-安全控制HTTP接口鉴权勾选流地址鉴权后401 Unauthorized如何播放调用接口? 1、安全控制1.1、HTTP接口鉴权1.2、流地址鉴权 2、401 Unauthorized2.1、携带token调用接口2.1.1、获取鉴权token2.1.2、调用其它接口2.1.2.1、携带 Co…...

wordpress建站怎么样/百度站长收录入口

本文为英国剑桥大学(作者:AlexGuy Kendall)的博士论文,共208页。 深度学习和卷积神经网络已经成为计算机视觉的主要工具,这些技术擅长于使用监督学习从数据中学习复杂的表示。特别地,在一定约束条件下&…...

动态网站和响应式网站/yandex搜索引擎

# 软件架构风格 软件架构设计的一个核心问题是能否使用重复的架构模式,即能否达到架构级的软件重用。 也就是说,能否在不同的软件系统中,使用同一架构。 软件架构风格是描述某一特定应用领域中系统组织方式的惯用模式。 架构风格反映了领域中…...

广州做网站好的公司/公司网站制作教程

作者:橙红年代 (https://juejin.cn/post/6923803717808422925)最近微博上曝出了很多瓜,"合成大西瓜"这个游戏也很火热,玩了一阵还挺有意思的。研究了一下原理,发现目前流传的版本都是魔改编译后的版本,代码经…...

杭州网页设计培训课程/百度seo推广怎么做

计算机之间的通信是以协议为基础的,客户端(用户)和服务端(网站)都按照协议的约定进行通信。HTTP的状态码就在HTTP的协议内,规定了很多的状态。客户端请求服务端后,服务端就返回结果,…...

wordpress商城怎么样/100%上热门文案

2020/7/28 依旧是和sql有着不解之缘的一天 总结一下在python中用sql语句的一些汇总 insertinsert into tablename(column1,column2...) values(value1,value2...) insert into tablename(column1,column2...) values(%s,%s...)---->然后你要传数据到这个里面去&#xff0…...

重庆九龙网站建设/销售课程视频免费

1、安装 flexible和 postcss-px2rem 自适应的开发方式下,仍然可以如此:你在设计图上量到的像素(px)是多少你就可以写多少px。很方便你开发项目哦 有图有代码,简单明了 npm 同时装下面2个东西,你也可以分…...