go语言学习之旅--函数(代码片段)

赵jc 赵jc     2022-11-28     784

关键词:

函数

GoLang函数介绍

函数的go语言中的一级公民,我们把所有的功能单元都定义在函数中,可以重复使用。函数包含函数的名称、参数列表和返回值类型,这些构成了函数的签名(signature)。
函数在使用之前必须先定义,可以调用函数来完成某个任务。函教可以重复调用,从而达到代码重用。

Go语言中函数特性

  • 1.go语言中有3种函数:普通函数、匿名函数(没有名称的函数)、方法(定义在struct上的函数)。
  • 2.go语言中不允许函数重载(overload),也就是说不允许函数同名。
  • 3.go语言中的函数不能嵌套函数,但可以嵌套匿名函数。
  • 4.函数是一个值,可以将函数赋值给变量,使得这个变量也成为函数。
  • 5.函数可以作为参数传递给另一个函数。
  • 6.函数的返回值可以是一个函数。
  • 7.函数调用的时候,如果有参数传递给函数,则先拷贝参数的副本,再将副本传递给函数。
  • 8.函数参数可以没有名称。

函数的定义

定义格式

func function_name([parameter list])[return_types] 
  函数体

语法解析

  • func:函数由func开始声明
  • function_name:函数名称,函数名和参数列表一起构成了函数签名。
  • [parameter list]:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
  • return_types:返回类型,函数返回一列值。return_types是该列值的数据类型。有些功能不需要返回值,这种情况下return_types不是必须的。
  • 函数体:函数定义的代码集合。

举例

func sum(a int, b int)(ret int) 
	ret = a + b
	return ret

func comp(a int, b int)(max int) 
	if a > b 
		max = a
	else 
		max = b
	
	return max

函数的返回值

函数可以有0或多个返回值,返回值需要指定数据类型,返回值通过return关键字来指定。return可以有参数,也可以没有参数,这些返回值可以有名称,也可以没有名称。go中的函数可以有多个返回值。

  • 1.return 关键字中指定了参数时,返回值可以不用名称。如果return省略参数,则返回值部分必须带名称
  • 2.当返回值有名称时,必须使用括号包围,逗号分隔,即使只有一个返回值
  • 3.但即使返回值命名了,return中也可以强制指定其它返回值的名称,也就是说return的优先级更高
  • 4.命名的返回值是预先声明好的,在函数内部可以直接使用,无需再次声明。命名返回值的名称不能和函数参数名称相同,否则报错提示变量重复定义
  • 5.return 中可以有表达式,但不能出现赋值表达式,这和其它语言可能有所不同。例如return a+b是正确的,但return c=a+b是错误的。

举例:

没有返回值

func f1() 
	fmt.Printf("没有返回值,只进行一些计算"

有一个返回值

func sum(a int, b int) (ret int) 
	ret = a + b
	return ret

多个返回值,且在return中指定返回的内容

func f2()(name string, age int) 
	name = "zjc"
	age = 30
	return name, age

多个返回值,返回值名称没有被使用

func f3()(name string, age int) 
	name = "zjc"
	age = 30
	return //等价于return name,age

return覆盖命名返回值,返回值名称没有被使用

func f4()(name string,age int) 
	n := "zjc"
	a := 30
	return n,a

匿名函数

Go语言函数不能嵌套,但是在函数内部可以定义匿名函数,实现一些简单功能调用。
匿名函数,就是没有名称的函数。

  • 语法格式如下
func (参数列表)(返回值)

举例

  • 普通情况
func main() 
	max := func(a int, b int) int 
		if a > b 
			return a
		else 
			return b
		
	
	i := max(1, 2)
	fmt.Printf("i: %v\\n", i)

  • 也可以在函数后添加()自己执行
func main() 
	//自己执行
	func(a int,b int) 
		max := 0
		if a > b 
			max = a
		else 
			max = b
		
		fmt.Printf("max: %v\\n", max)
	(1, 2)

也可以把匿名函数定义成全局变量

var (
    fun1 = func(n1 int, n2 int) int 
        return n1 * n2
    
)
 
func main() 
    fmt.Println(fun1(42, 44))

闭包

闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。或者说是函数和其引用环境的组合体。I闭包指的是一个函数和与其相关的引用环境组合而成的实体。简单来说,闭包=函数+引用环境。首先我们来看一个例子:

func AddUpper() func (int) int 
    var n int = 10
    return func(x int) int 
        n = n + x
        return n
    

AddUpper()返回的匿名函数,引用了匿名函数外的n,所以AddUpper内部形成了闭包。AddUpper的调用如下:

	f := AddUpper()
    fmt.Println(f(1)) // 11
    fmt.Println(f(3)) // 14
    fmt.Println(f(3)) // 17

由于形成了匿名函数+外部引用的形式,所以每次调用AddUpper()时,n都会继承上一次调用的值。

就当n是AddUpper()的属性,一个对象只会初始化一次。

	f := AddUpper()
    fmt.Println(f(1)) // 11
    fmt.Println(f(3)) // 14
    fmt.Println(f(3)) // 17
    
    g := AddUpper()
    fmt.Println(g(4)) // 14

defer

定义

  • Go语言中的defer
    语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行,也就是说,先被defer的语句最后被执行,最后被
    defer的语句,最先被执行。

defer特性

  • 1.关键字defer用于注册延迟调用。
  • 2.这些调用直到return前才被执。因此,可以用来做资源清理。
  • 3.多个defer 语句,按先进后出的方式执行。
  • 4.defer 语句中的变量,在defer声明时就决定了。

defer用途

  • 1.关闭文件句柄
  • 2.锁资源释放
  • 3.数据库连接释放

举例

func main() 
	fmt.Println("start")
	defer fmt.Println("step1")
	defer fmt.Println("step2")
	defer fmt.Println("step3")
	fmt.Println("end")

init函数

定义

  • Go朗有一个特殊的函数init函数,先于main函数执行,实现包级别的一些初始化操作

init函数的特点

  • init函数先于main函数自动执行,不能被其他函数调用
  • init函数没有输入参数、返回值
  • 每个包可以有多个init函数
  • 包的每个源文件也可以有多个init函数,这点比较特殊
  • 同一包的init执行顺序,golang没有明确定义,编程时注意程序不要依赖这个执行顺序
  • 不同包的init函数按照包导入的依赖关系决定执行顺序

golang的初始化顺序

  • 初始化顺序:变量初始化–>init–>main()

举例

var i int = initVar()
func init() 
	//初始化
	fmt.Println("init......")

func initVar() int 
	//初始化变量
	fmt.Println("initVar...")
	return 100

func main() 
	fmt.Println("main......")

go学习之旅go语言安装及环境配置教程(代码片段)

一、前言Go(又称Golang)是Google开发的一种静态强类型、编译型的编程语言。Go语言的主要特点包括:自动垃圾回收、更丰富的内置类型、函数多返回值、错误处理、匿名函数和闭包、类型和接口、并发编程、反射、语言交互性... 查看详情

go语言学习之旅--函数(代码片段)

函数GoLang函数介绍Go语言中函数特性函数的定义匿名函数闭包deferinit函数GoLang函数介绍函数的go语言中的一级公民,我们把所有的功能单元都定义在函数中,可以重复使用。函数包含函数的名称、参数列表和返回值类型... 查看详情

go语言学习之旅--go语言环境安装(代码片段)

前言笔者已经自学python大概已经几个月了,但是工作繁忙,而且工作中未用到python的知识。于是就渐渐生疏了,这是下定决心学习go,是因为公司有一台go编写的报表系统,而且公司逐渐在想docker转,学习go更又助于未来的工作。... 查看详情

go语言学习之旅--结构体(代码片段)

结构体go语言类型定义go语言类型别名go语言类型定义和类型别名的区别结构体go语言结构体的定义声明一个结构体变量结构体的初始化访问结构体成员匿名结构体结构体指针举例使用new关键字创建结构体指针访问结构体指针成员... 查看详情

go语言学习之旅--结构体(代码片段)

结构体go语言类型定义go语言类型别名go语言类型定义和类型别名的区别结构体go语言结构体的定义声明一个结构体变量结构体的初始化访问结构体成员匿名结构体结构体指针举例使用new关键字创建结构体指针访问结构体指针成员... 查看详情

go语言学习之旅--文件os(代码片段)

Go语言学习之旅--文件os库OS文件、目录操作File文件读操作File文件写操作os包进程相关操作os包和环境相关的方法博客根据B站《golang入门到项目实战[2021最新Go语言教程,没有废话,纯干货》视频整理的,如有错误请大... 查看详情

go语言学习之旅--文件os(代码片段)

Go语言学习之旅--文件os库OS文件、目录操作File文件读操作File文件写操作os包进程相关操作os包和环境相关的方法博客根据B站《golang入门到项目实战[2021最新Go语言教程,没有废话,纯干货》视频整理的,如有错误请大... 查看详情

go语言学习之旅--gorm(代码片段)

Go语言学习之旅--gormgorm概述ORM简介安装gorm声明模型模型定义约定gorm.Modelgorm连接到数据库快速入门gorm的增删查改增gorm创建记录用指定的字段创建记录批量插入查检索单个对象用主键检索检索全部对象String条件Struct&Map条件更... 查看详情

go语言学习之旅--初识golang(代码片段)

Go语言简介特点编码风格Go安装测试Go(又称Golang)是Google的RobertGriesemer,RobPike及KenThompson开发的一种静态强类型、编译型语言。Go语言语法与C相近,但功能上有:内存安全,GC(垃圾回收),结... 查看详情

go语言学习之旅--接口(代码片段)

接口接口实现接口必须实现接口中的所有方法golang接口值类型接收者和指针类型接收者golang接口和类型的关系一个类型实现多个接口多个类型实现同一个接口golang接口嵌套接口go语言的接口,是一种新的类型定义,它把所... 查看详情

go的100天之旅-03变量(代码片段)

变量变量介绍变量这个词来源于数学,类似方程中的x、y,代表的是存储在计算机中的值。这里主要介绍Go和其它编程语言不一样的地方,在前面我们提到过,Go是一门静态语言。静态语言区别动态语言一个重要的特性就是变量的... 查看详情

go语言学习之旅--基础语法(代码片段)

变量变量有三种声明方式第一种:var变量名类型=值variint=10第二种:var变量名=值varj=10第三种:变量名:=值,自动推导类型name:="zjc"一些特殊的情况:一次声明多个变量,变量名和值... 查看详情

go语言学习之旅--基础语法(代码片段)

变量变量有三种声明方式第一种:var变量名类型=值variint=10第二种:var变量名=值varj=10第三种:变量名:=值,自动推导类型name:="zjc"一些特殊的情况:一次声明多个变量,变量名和值... 查看详情

go的100天之旅-06数组和slice(代码片段)

目录数组Slice数组Go的数组和其它语言基本上一样,是长度固定的特定类型元素组成的序列,这基本上是所有语言数组的特性。和其它语言相比差异主要在声明和初始化的写法上,下面是简单声明一个数组:vara[5]intfmt.Println(a[0])fm... 查看详情

go入门-包,函数和变量(代码片段)

主要内容来自中文版的同名教程Go语言之旅其目的为总结要点包,函数和变量包import语法,多个用括号换行扩起,包之间不需要间隔符,用引号引起import("fmt""math/rand")//官方认为分组导入比多个导入更好//用`.`引用包内对象,仅有... 查看详情

python学习之旅--函数(代码片段)

1,函数介绍目的:函数的作用"""函数的作用:1,代码复用性提高了2,可维护性提高"""2,函数定义目的:知道函数的组成,定义,调用操作流程:"""函数定义:def函数名(参数1:类型1,参数2:类型2)->声明返回值类型...r... 查看详情

go语言学习之旅--接口(代码片段)

接口接口实现接口必须实现接口中的所有方法golang接口值类型接收者和指针类型接收者golang接口和类型的关系一个类型实现多个接口多个类型实现同一个接口golang接口嵌套接口go语言的接口,是一种新的类型定义,它把所... 查看详情

go语言学习之旅--接口(代码片段)

接口接口实现接口必须实现接口中的所有方法golang接口值类型接收者和指针类型接收者golang接口和类型的关系一个类型实现多个接口多个类型实现同一个接口golang接口嵌套接口go语言的接口,是一种新的类型定义,它把所... 查看详情