学习golang(7) 初探:函数(1)

简介: 学习golang(7) 初探:函数(1)

虽然编程语言都大相径庭,但是每个语言都还是有一些特性的,所以我们还是要保持空杯心态去看待这件事情,不焦虑,不浮躁,如果觉得自己学到了某些,那么可以将它整理成文档,这也许就是掘金更文的初衷吧。



为什么需要函数


我们可以将一个非常复杂的工作,分为多个子任务,分而治之,不仅如此,假如我们编写一个程序,该程序有n条语句,被多次使用,那么我们有2种调用方法,1. 直接在程序中使用相同的代码 2. 创建一个函数,并在主函数中执行函数即可。还有一个点是,我们使用函数,让多人协作变得更加容易。


为什么我们需要函数?


  • 让多人协作变得很容易
  • 减少没必要的重复代码
  • 提高代码可读性



举个例子:

例如我们在程序中经常输出一些语句fmt.Println("123")这里其实就是函数,只不过它为系统函数,我们为此,不需要重新打印语句,而直接调用即可。


再举个例子:


例如我们想写一个程序,该程序的主要功能为:把大象放进冰箱,那么我们将此划分为三个函数


  • 函数1: 根据大象的体型,找到能够装这么大的并且,并且返回 地址和冰箱门
  • 函数2: 调用函数1,把大象运至该地址
  • 函数3:将大象放入冰箱,并且关闭冰箱门

为此,我们就可以将这个工程,分为三个人,或者三个不同部分协作处理了,每人/每个团队只用根据文档,返回相应的值即可。




函数的调用逻辑


函数调用逻辑概述


函数的调用过程逻辑非常复杂,涉及到了很多底层的东西,我看了一阵子,没怎么学过汇编,我也没怎么看懂,我们来看调用栈的过程吧,


假设 主函数中 调用了函数A,函数A调用了 函数B ,函数B又调用了函数C,那么其调用过程应该为

image.png


最先被调用的函数(例如: main) 最后被执行完毕

最后被调用的函数(C)最先被执行完毕



尝试使用调试工具分析调用逻辑


我们虽然暂时还看不懂,汇编的东西,但是我们可以debug一下函数调用栈

操作步骤


  • layout src显示源代码窗口
  • l查看代码
  • 使用b设置断点
  • 使用run运行代码
  • 使用c切换到端点
  • 使用bt查看调用栈


image.png


如图,我们能够清楚的看到函数调用栈:

main函数最先入栈,最后一个出栈,而c函数最后入栈,却最先出栈。



函数的基本使用


函数格式

go函数格式如下

func 函数名称(函数参数列表) (返回值列表) {
    ...
}


例如我们写一个返回程序,该程序有一个函数add1,add1接收一个int的参数,并且返回该参数-1的值


函数定义如下

func add1(x int)(int) {
  return x-1
}


image.png

我们执行该程序

image.png


返回多个值


我们可以使用go返回多个值,还记得之前我们写的tcp服务器 么? 其中就返回了多个值

语法如下

func 函数名称(参数)(返回类型A,返回类型B) {
}

我们来尝试下

我们改写下程序,将原参数-1 和 原参数 的值返回回去

image.png


我们执行一下语句

image.png


不仅如此,我们还可以隐式返回,我们修改下代码

我们在函数返回上定义变量,然后赋值起变量,最后使用return,此语句也会返回2个参数,不过一般用的不是很多

image.png


我们执行下

image.png


以上就是函数的基本使用,简单吧,是不是和其他语言差不多。



go函数的特性

除了和别的语言差不多的函数声明,go还提供了其他的函数申明,来看下


匿名函数

我们再func后没有添加函数名称,这个称之为匿名函数,我们可以将上述例子修改为匿名函数的形式

image.png


我们执行下代码

image.png


什么时候会用到匿名函数呢?

我们若仅在某个时刻使用该函数一次,后面我们就不用了,我们则可以使用匿名函数,比如,我们利用协程处理事情


image.png


我们执行下

image.png


defer代码


我们进程在go中看到defer, 其实它的作用为: 在函数结束完毕后,执行defer语句(不管函数是否正常都会执行defer)

例如,我们有如下代码

image.png


从上述我们可以知道,defer是在return结束完毕后再执行的,具体的我们执行下代码看看


image.png


还有一点,若我们在写defer之前,程序就崩溃了,此时是不会调用defer语句的,例如

image.png


我们执行下代码

image.png


总结


go因为没有try,所以,我们判断是否正常,就很需要函数返回正常的值,和error,我们再判断error是否为nil,若为nil则代表函数执行成功,否则执行出错。


此外,defer真的很强大,在别的语言中,我们一般打开一个文件,都会在最后关掉句柄,虽然go有回收机制,但是回收机制,一般用于在程序中申请的变量,不包括打开的系统资源,所以,我们可以在打开后,设置defer关闭文件,这样绝不会出错,例如



fs , err := os.Open("123.txt")
if err != nil {
        return
}
defer fs.Close()


今天就这样吧,今天学gdb花了太多时间了。,以前没怎么用gdb调试过,我一般调试代码还没有达到栈级别,都是使用打印大法print调试的。

溜了 溜了


相关文章
|
3月前
|
Go
Golang语言之函数(func)进阶篇
这篇文章是关于Golang语言中函数高级用法的教程,涵盖了初始化函数、匿名函数、闭包函数、高阶函数、defer关键字以及系统函数的使用和案例。
69 3
Golang语言之函数(func)进阶篇
|
3月前
|
Go
Golang语言之函数(func)基础篇
这篇文章深入讲解了Golang语言中函数的定义和使用,包括函数的引入原因、使用细节、定义语法,并通过多个案例展示了如何定义不返回任何参数、返回一个或多个参数、返回值命名、可变参数的函数,同时探讨了函数默认值传递、指针传递、函数作为变量和参数、自定义数据类型以及返回值为切片类型的函数。
75 2
Golang语言之函数(func)基础篇
|
2月前
|
安全 Java Go
【Golang入门】简介与基本语法学习
Golang语言入门教程,介绍了Go语言的简介、基本语法、程序结构、变量和常量、控制结构、函数、并发编程、接口和类型、导入包、作用域以及错误处理等关键概念,为初学者提供了一个全面的学习起点。
32 0
|
3月前
|
Unix Go
Golang语言标准库time之日期和时间相关函数
这篇文章是关于Go语言日期和时间处理的文章,介绍了如何使用Go标准库中的time包来处理日期和时间。
61 3
|
7月前
|
Go
golang中置new()函数和make()函数的区别
golang中置new()函数和make()函数的区别
|
4月前
|
机器学习/深度学习 存储 人工智能
Golang bytes 包学习
Golang bytes 包学习
27 3
|
5月前
|
编译器 Go C语言
通过例子学习在golang中调试程序
【7月更文挑战第4天】Go语言支持使用cgo进行汇编调试,官方文档在golang.org/doc/asm。注意,调试Go运行时可能遇到变量不可用或行号错误,需谨慎使用step命令。
78 1
通过例子学习在golang中调试程序
|
7月前
|
Go
Golang深入浅出之-Go语言函数基础:定义、调用与多返回值
【4月更文挑战第21天】Go语言函数是代码组织的基本单元,用于封装可重用逻辑。本文介绍了函数定义(包括基本形式、命名、参数列表和多返回值)、调用以及匿名函数与闭包。在函数定义时,注意参数命名和注释,避免参数顺序混淆。在调用时,要检查并处理多返回值中的错误。理解闭包原理,小心处理外部变量引用,以提升代码质量和可维护性。通过实践和示例,能更好地掌握Go语言函数。
136 1
Golang深入浅出之-Go语言函数基础:定义、调用与多返回值
|
7月前
|
Go
golang学习参考记录
golang学习参考记录
|
7月前
|
JSON Go 数据格式
golang学习7,glang的web的restful接口结构体传参
golang学习7,glang的web的restful接口结构体传参