Golang基础--06--函数function

Golang function 函数详解 对于任何语言而言,函数都是结构化编程中的重要一环,通过函数机制,可以把一个大的模块分解成多个小任务,让代码结构更清晰,可复用性大大提高。 本文将介绍如何定义,调用函数,如何定义和接收函数错误,以及 golang 特有的可变参数,闭包,defer,panic 和 recover 等机制。 阅读详情

目录

Tips

  • Go函数不支持 嵌套,重载 和 默认参数
  • 但支持以下特性: 无需声明原型,不定长度变参,多返回值,命名返回值参数,匿名函数,闭包
  • 定义函数使用关键字func,并且左大括号不能另起一行

函数定义,不定长变参,传递值类型与引用类型

func main(){
    a,b := 1,2
    //传入值类型的拷贝,(int,string),不会改变这里的值
    B(a,b)
    fmt.Println("a,b=",a,b)
    fmt.Println(A())
    ss := []int{5,6,7,8}
    //传入的参数是slice,是数组地址的拷贝,会改变这里的值,类似指针
    C(ss)
    fmt.Println("ss=",ss)
}
func A()(int, int, int){
    a,b,c := 1,2,3
    return a,b,c
}
func B(s ...int){
    //a是个slice,不定长变参,只能作为最后一个参数
    s[0]=3
    s[1]=4
    fmt.Println("s=",s)
}
func C(s []int){
    s[0] = 55
    s[1] = 66
    s[2] = 77
    s[3] = 88
    fmt.Println(s)
}
/*
> Output:
command-line-arguments
s= [3 4]
a,b= 1 2
1 2 3
[55 66 77 88]
ss= [55 66 77 88]
*/
  • 值类型传递和引用类型传递都是拷贝,但是值类型是拷贝值,而引用类型是拷贝地址

一切皆类型,包括函数

  • Go语言中,一切皆类型,函数也能作为一种类型使用
func main(){
    a := A
    a()
}
func A(){
    fmt.Println("Func A")
}
/*
> Output:
command-line-arguments
Func A
*/

匿名函数和闭包

匿名函数

-匿名函数不能是最外层函数

func main(){
    a := func(){
        fmt.Println("Func A")
    }
    a()
}
func A(){
    fmt.Println("Func A")
}
/*
> Output:
command-line-arguments
Func A
*/

闭包

  • 闭包函数的作用:返回一个匿名函数
func main(){
    f := closure(10)
    fmt.Println(f(1))
    fmt.Println(f(2))
}
func closure(x int) func(int) int {
    fmt.Printf("outside %p\n", &x)
    return func(y int) int {
        fmt.Printf("%p\n", &x)
        return x * y
    }
}
/*
> Output:
command-line-arguments
outside 0xc042054080
0xc042054080
10
0xc042054080
20
*/

defer用法

  • defer的执行方式类似其他语言的析构函数,在函数体执行结束后,按照调用顺序的相反顺序执行(好像递归返回那样吧)
  • 就算函数发生了严重错误也会执行
  • 支持匿名函数的使用
  • 常用于资源清理,文件关闭,解锁以及记录时间等操作
  • 通过与匿名函数配合可以在return之后修改函数结果
  • 如果函数体内某个变量作为defer时匿名函数的参数,则在定义时就已经获得拷贝,否则则是引用某个变量的地址
func main(){
    fmt.Println("a")
    defer fmt.Println("b")
    defer fmt.Println("c")
}
//a,c,b
  • 把return语句看做赋值+返回RET指令两部分,defer是插入在中间的,并且注意defer里面的函数操作的是返回值还是别的变量,匿名函数的参数是值传递还是引用传递,值传递就不会改变返回值啦
  • 参照大佬解析
  • 注意:defer后面定义的匿名函数要在最后加上(参数)
func main(){
    for i:=0; i<3; i++ {
        defer func() {
            fmt.Println(i)
            }()
    }
    fmt.Println("a")
    defer fmt.Println("b")
    defer fmt.Println("c")
}
/*
> Output:
command-line-arguments
a
c
b
3
3
3
*/

panic 与 recover,错误处理机制

  • Go没有异常机制,但是panic/recover模式来处理错误
  • panic可以在任何地方引发,但是recover只有在defer调用的函数
func main(){
    A()
    B()
    C()
}
func A() {
    fmt.Println("Func A")
}
//defer要放在panic前面才有效,程序遇到panic就停了,所以要在这之前先注册defer的函数,且panic语句也不会执行了
func B() {
    defer func() {
        if err:=recover(); err!=nil{
            fmt.Println("recover in B")
        }
    }()
    panic("panic in B")
}
func C() {
    fmt.Println("Func C")
}
/*
> Output:
command-line-arguments
Func A
recover in B
Func C
*/

综合例子

func main(){
    var fs = [4]func(){}
    for i := 0; i<4; i++ {
    //值拷贝i+defer先进后出的输出
        defer fmt.Println("defer i= ",i)
        //引用拷贝(匿名函数没有参数,引用的i是外层的地址拷贝,为4)+defer
        defer func() {fmt.Println("defer_closure i= ",i)}()
        //引用拷贝(匿名函数没有参数,引用的i是外层的地址拷贝,为4)
        fs[i] = func(){ fmt.Println("closure i= ",i)}
    }
    for _,f := range fs {
        f()
    }
}
/*
> Output:
command-line-arguments
closure i=  4
closure i=  4
closure i=  4
closure i=  4
defer_closure i=  4
defer i=  3
defer_closure i=  4
defer i=  2
defer_closure i=  4
defer i=  1
defer_closure i=  4
defer i=  0
*/
Golang 函数定义及使用 Golang 函数定义及基础使用 阅读详情

相关推荐

深入解析SSD报错“READ FPDMA QUEUED”:从诊断到修复全流程

本文深入解析了SSD报错“READ FPDMA QUEUED”的含义、成因与全流程解决方案。该错误通常指示硬盘硬件或健康状态问题。文章详细介绍了如何通过系统日志定位错误、解读关键的S.M.A.R.T.健康报告(重点关注重分配扇区计数等指标),并逐步进行硬件排查(如更换SATA数据线)、软件修复与数据抢救,最终指导用户根据诊断结果做出维修或更换SSD的决策。

weixin_29233333的博客 399

爱上开源之golang入门至实战第四章-函数(func)(一)

函数是各种编程语言不可缺少的一部分,编程的过程也就是通过函数的实现和调用来完成我们需要达到的编程的目的;把函数这个章节的内容归入到了数据类型;我一直犹豫不决;按照一般的出牌顺序,函数就处于编程的过程,不应该纳入到数据类型里来,但是我觉得纳入到这里,能够更加明显的体现出go语言里的函数所不同的地方。下面就听我来叨咕叨咕,golang里的函数。...

645

微波无源器件 功分器1 新型方波导双模无功功分器

本名证明了一种基于有着特定功能的(dedicated)T性匹配元件(散射件)的进化结点的新型波导双模两路功分器的可行性。这个散射件,有着面向三个部分的匹配部分,提供了等效功分并且朝着对应的输出端口传输矩形波导的两个TE10/TE01正交模式。所提出的设计紧凑,易于比例变化并且能够级联来获得。

qq_45245770的博客 1391

Go语言-基础知识-第6章-【func 函数】函数定义

函数构成了代码执行的逻辑结构,在Go语言中,函数的基本组成为:关键字 func、函数名、参数列表、返回值、函数体和返回语句,每一个程序都包含很多的函数,函数是基本的代码块。 因为Go语言是编译型语言,所以函数编写的顺序是无关紧要的,鉴于可读性的需求,最好把 main() 函数写在文件的前面,其他函数按照一定逻辑顺序进行编写(例如函数被调用的顺序)。 编写多个函数的主要目的是将一个需要很多行代码的复杂问题分解为一系列简单的任务来解决,而且,同一个任务(函数)可以被多次调用,有助于代码重用(事实上,好的程序..

xyz的专栏 7423

机械工程师如何用Codex实现CAD自动化:从重复劳动到智能设计

在机械设计领域,CAD二次开发长期面临学习门槛高、维护成本大的难题。随着AI编程助手如Codex的出现,通过自然语言生成可执行代码,工程师无需精通编程即可实现图纸批量处理、BOM表自动生成、参数化建模等任务。这种技术将重复性操作自动化,显著提升设计效率,让工程师聚焦于核心创新。应用场景涵盖批量修改图纸属性、跨软件数据流转、自动打印等。本文分享机械工程师利用Codex落地自动化的实战经验与避坑指南。

weixin_32296621的博客 359

在 Ansys CFX Pre 中配置 RGP 表的分步指南

掌握在 Ansys CFX Pre 中设置 RGP 表的技巧,以优化仿真精度和效率。

jkh920184196的博客 1664

[08]Golang的函数体function

func 函数名(传入值) (返回值) {} 运行结果: 函数使用slice,是对slice的地址拷贝操作 运行结果: 函数调用数组,仅仅是数值的拷贝是引用类型 运行结果: 函数可以通过指针,来调用修改值类型 运行结果: 函数类型的使用(Go语言中一切皆类型) 运行结果: 匿名函数不可以作为顶级函数,只在别的函数体当中,不能当做最外层函数 运行结果: 运行结果: 三次调用指向的x是同一个x 运行结果: 的执行方式类似其他语言中的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行即使函数发生严重错误

Sugarpromax的博客 337

【机械臂算法】基于最小惯性参数集的动力学辨识仿真实践

本文深入探讨了机械臂动力学参数辨识的核心挑战与解决方案,重点阐述了基于最小惯性参数集的理论与方法。通过分析PUMA560实例,详细介绍了利用QR分解法或符号推导法获取可辨识参数集,并系统讲解了从激励轨迹设计、仿真数据采集、线性系统求解到模型验证的完整实践流程,为高精度动力学建模与控制奠定了坚实基础。

weixin_29054399的博客 376

Golang基础_06-函数function

目录 目录 Tips 匿名函数和闭包 匿名函数 闭包 defer用法 panic 与 recover,错误处理机制 综合例子 目录 @ Tips Go函数不支持 嵌套,重载 ...

169

24、流化催化裂化的分子建模

本文探讨了流化催化裂化(FCC)的分子建模方法,重点分析了如何通过机理建模和模型修剪策略(如反应规则和随机规则)来减少计算复杂度,同时保持化学意义。文章还介绍了定量结构反应性关联(QSRC)在动力学参数确定中的应用,以及结焦对催化剂活性的影响。通过这些方法,FCC反应模型能够在预测产物分布的同时,显著提高计算效率。

s8t9u0v1w的博客 141

【ComfyUI】Wan 2.2 14B 首尾帧转视频 平滑过渡

本文介绍了基于 Wan2.2 ComfyUI 的视频生成工作流,通过预训练模型、提示词与参考图像的结合,实现高质量视频合成。工作流采用高低噪声模型与 LoRA 模块优化风格与细节,确保画面过渡平滑稳定。核心流程包括模型加载、图像输入、提示词编码、潜空间采样、解码与视频合成,最终生成动态转场视频。节点设计涵盖 CLIPTextEncode、KSamplerAdvanced 等关键模块,协同完成从文本到视频的全链路生成。正向提示词作为核心驱动力,直接影响视频的动作、镜头与画面变化。

Mr数据杨 1702

in function ‘int main()’_Golang基础入门06 | Function

在任何编程语言中,都必须编写优秀的代码。 优秀的代码意味着高效运行和可读性强,大部分人(尤其是程序员或开发人员)都容易理解该代码。通过函数将大部分代码拆分为较小的代码块。Function in Go函数是一段代码,用于执行可以重用的特定任务。//func receiver functionName(parameters types) return type func (receiver)func...

weixin_32711097的博客 1811

【k8s故障处理篇】calico-node启动失败“Felix is not live: Get “http://localhost:9099/liveness” 解决办法(V1.30.3版本)

【k8s故障处理篇】calico-node启动失败“Felix is not live: Get “http://localhost:9099/liveness” 解决办法(V1.30.3版本)

jks212454的博客 1091

2022-06-18:golang与 C++数据结构类型对应关系是怎样的?

2022-06-18:golang与 C++数据结构类型对应关系是怎样的?答案2022-06-18:uintptr和unsafe.Pointer相当于c++的void*,也就是任意指针。 uintptr可以参与指针运算,unsafe.Pointer不能参与指针运算。c++和golang对照表如下:go类型和uintptr的相互转换如下:...

福大大架构师每日一题 2万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

06《Go语言入门》Go程序结构、入口、退出返回值及获取命令函参数

目录Go程序结构程序入口退出返回值获取命令行传参支持???? Go程序结构 一个基本的Go程序代码由三部分构成: 包 引入依赖 main函数程序入口 // 包,表明代码所在的模块(包) package main // 引入代码依赖 // IDE会自动导入包,所以可以直接使用fmt,而不需要写下面代码 import "fmt" // 程序入口,功能实现 func main() { fmt.Println("Start") fmt.Println("Hello, World!") fmt.Pri

干志雄的博客 929

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

二进制函数_Go二进制文件逆向分析从基础到进阶——MetaInfo、函数符号和源码文件路径列表...

书接前文,本文主要介绍 Go 二进制文件中 Meta Information 的解析,与函数符号和源码文件路径列表的提取。最后详细介绍一下Moduledata这个结构。传送门:Go二进制文件逆向分析从基础到进阶——综述05Meta information>>>>5.1Go Build ID每一个 Go 二进制文件内,都有一个独一无二的 Build ID,详...

weixin_30368405的博客 934

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

learn go function callback

package main // 参考文档: // https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/06.7.md import ( "fmt" ) func main () { callback(1, Add) } func Add(a, b int) {...

weixin_34194551的博客 226

06 Errors For Go1.13

Errors before For 1.13 最简单的错误检查: if err != nil { // sth went wrong } 有事我们需要对sentinel error进行检查: var ErrNotFound = errors.New(" not found") if err != ErrNotFound { // sth wasn‘t found } 实现了error interface的自定义error struct,进行断言使用获取更丰富的上下文: type No

YouSec995 的博客 285

Go语言函数定义与使用

函数是Go语言编程的核心构建块,它封装了可复用的代码逻辑,接受输入参数并返回结果。掌握函数的定义、调用和高级特性,是编写清晰、高效Go代码的关键。

星航夜空的帆舟 207

learn go anonymous function

package main // 参考文档: // https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/06.8.md import "fmt" func main() { f() } func f() { for i := 0; i < 4; i++ { ...

weixin_34367845的博客 84

go 学习

1、switch 的case 自带 break 属性; 2、可以并列初始化、赋值; 3、闭包/匿名,多次调用,可以使局部变量保持静态属性; https://www.runoob.com/go/go-function-closures.html

weixin_41565755的博客 703

Go语言基础

一、Go基础 标识符: ​ go语言中的标识符由字母数字和下划线(_)组成,并且只能以字母和下划线(_)开头 关键字: ​ 关键字是指编程语言中预先定义好的具有特殊含义的标识符。关键字和保留字都不建议用作变量名。 Go语言有25个关键字: 关键字 break default func interface select case defer go map struct chan else goto package switch const fallthrough if

有用的话关个注,点个赞,收个藏🫶。 1919
上一篇: Golang基础--05--map
下一篇: Golang基础--07--结构struct
ListentTome
博客等级 码龄9年 3粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值