0

0

如何在Golang中定义与调用函数 Go语言函数参数传递机制

P粉602998670

P粉602998670

发布时间:2026-03-01 14:01:10

|

957人浏览过

|

来源于php中文网

原创

go函数定义必须显式声明参数和返回类型,不支持类型推导;参数为值传递,map/slice等修改底层数组可影响外部,但重赋值无效;变参须在末尾且类型一致;闭包捕获变量而非值。

如何在golang中定义与调用函数 go语言函数参数传递机制

Go 函数定义必须显式声明每个参数类型和返回类型

Go 不支持类型推导,func 声明里漏写任一参数或返回值的类型,编译直接报错。比如 func add(a, b int) int 合法,但 func add(a, b) intfunc add(a int, b int)(缺返回类型)都不行。

常见错误是把多个同类型参数简写成 a, b int 误以为是“批量声明”,其实这是合法语法——但仅限于相邻且类型相同;一旦中间夹了不同类型的参数,就必须逐个写类型,比如 func process(name string, age int, active bool),不能缩成 name, age, active string, int, bool

  • 返回值若为单个,可省略括号:func now() time.Time
  • 多个返回值必须用括号包裹:func split(s string) (string, string)
  • 命名返回值(如 func count() (n int))会让函数体中直接用 n = 42 赋值,但容易掩盖逻辑,不建议在复杂函数中使用

Go 所有函数参数都是值传递,包括 slice、map、channel、interface

这点最容易误解:看到 func modify(m map[string]int) 就以为“传的是引用”,实际上传的是 map 类型的 header 值(包含指针字段),所以修改 m["k"] = v 会影响原 map;但若在函数内重新赋值 m = make(map[string]int),外部变量完全不受影响。

真正“不可变”的是 struct 和数组:传入 [3]intPerson{},函数内任何改动对外都不可见;想改就得传指针 *Person

立即学习go语言免费学习笔记(深入)”;

飞书知识问答
飞书知识问答

飞书平台推出的AI知识库管理和智能搜索工具

下载
  • slice 同理:能改底层数组元素,但不能通过 s = append(s, x) 改变原始 slice 的长度/容量(除非原 slice 是指针解引用而来)
  • string 是只读字节序列,传参后无法修改内容,也不需要指针
  • 性能上,小 struct(如 type Point struct{ x, y float64 })传值开销小;大 struct 建议传 *T 避免拷贝

调用函数时,实参与形参数量、顺序、类型必须严格匹配

Go 没有默认参数、没有重载、不支持按名传参。少传、多传、类型不符,编译器立刻报错,比如 add(1, "2") 会提示 cannot use "2" (type string) as type int in argument to add

唯一例外是变参函数(...T),但必须放在参数列表末尾,且调用时要么传零个,要么传同类型多个值,或一个切片加 ... 展开:

func sum(nums ...int) int {
    s := 0
    for _, n := range nums {
        s += n
    }
    return s
}
// 正确调用:
sum(1, 2, 3)
sum([]int{1,2,3}...)
// 错误调用:
sum(1, []int{2,3}...) // 类型混用,编译失败
  • 变参本质是语法糖,函数内接收到的是一个 []T,不是“可选参数”
  • 如果已有切片想传给非变参函数(比如 fmt.Println),必须用 ... 展开,否则类型不匹配
  • 不要为了“兼容性”在已有函数末尾加 ...interface{},这会让调用意图模糊,也掩盖真实接口需求

闭包捕获变量时,捕获的是变量本身,不是当时值

这是并发和循环中高频踩坑点。比如在 for 循环里启动 goroutine 并引用循环变量,所有 goroutine 最终看到的是循环结束后的最终值。

典型错误写法:

for i := 0; i < 3; i++ {
    go func() {
        fmt.Println(i) // 全部打印 3
    }()
}
  • 修复方式之一:在循环内用局部变量绑定当前值,val := i; go func() { fmt.Println(val) }()
  • 修复方式之二:把 i 作为参数传入闭包,go func(v int) { fmt.Println(v) }(i)
  • 注意:闭包捕获的是栈/堆上的变量地址,只要变量生命周期没结束,闭包就能访问;但如果变量已释放(如函数返回后局部变量),再访问就是未定义行为

函数是一等公民,但闭包不是“快照”,它活在变量的生命周期里——这点比参数传递机制更隐蔽,也更常出问题。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

207

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

242

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

352

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

406

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

408

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

200

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1212

2025.06.17

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

6

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 5.7万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号