Go基本代码结构
Go基本代码结构
第一个程序:
// main 包是程序的入口点 package main import "fmt" // 导入fmt包,用于格式化输入输出 /* main 函数是程序的启动函数 它是Go程序的入口点,执行时打印"Hello 世界!"到控制台 */ func main() { fmt.Println("Hello 世界!") }
Go程序运行指令:go run xxx.go
;Go程序编译指令:go build xxx.go
包的概念
package
关键字代表的是当前go文件属于哪一个包。在Go语言中,程序的构建基于包(Package)这一核心概念,开发者通过将多个包有机链接在一起来完成程序构建。程序的基本调用单元是包而非单个.go文件,每个包对应一个独立的目录,目录内的所有.go源文件共享作用域:变量、常量、函数及其他类型在包内自动可见,无需显式导入。
当main
包代码量较大时,开发者可将其合理拆分到多个.go文件中,只需确保每个文件首行都包含package main
声明。这种拆分方式既能保持代码的可维护性,又符合Go语言的模块化设计思想。
编译规则方面需特别注意:包含package main
声明的包通过go build
命令编译时会生成可执行文件,而非main
包(如package pack1
)在编译时会生成pack1.a
格式的静态库文件,这类包通常作为功能模块被其他程序引用。
关于包命名规范,所有包名推荐采用全小写字母命名,这种风格既符合Go语言官方代码规范,也有助于提升代码可读性。建议采用简洁的单词命名(如utils
、model
等),避免使用下划线或驼峰式命名,通过语义化的名称直观体现包的功能定位。
包的导入
在Go语言中,import
关键字用于导入外部包,导入后可以访问该包中所有公开的代码对象(如变量、函数、类型等)。为了避免命名冲突,包内的标识符必须唯一,但不同包中允许存在相同的标识符,因为可以通过包名区分,例如 pack1.Thing
和 pack2.Thing
。
Go语言通过标识符的首字母大小写来控制访问权限:
- 大写字母开头的标识符(如
Group1
)是导出的,可以被外部包访问(类似public
)。 - 小写字母开头的标识符是私有的,仅在包内可见(类似
private
)。
需要注意的是,大写字母不仅限于ASCII字符,任何Unicode编码的大写字符(如希腊文)均可用于导出标识符。
多包导入:
// import "fmt" // import "os" import ( "fmt" "os" ) // 更推荐这种方法导入多个包,而不是上面的方法
别名导入: 可以解决包名之间的名称冲突
import ( crand "crypto/rand" mrand "math/rand" )
匿名导入: 仅执行包的init
函数
import ( "fmt" _ "math" // 下划线表示匿名导入 )
如果你导入了一个包却没有使用它,则会在构建程序时引发错误,如
imported and not used: os
,这正是遵循了 Go 的格言:“没有不必要的代码!“。
注释
在Go语言中,注释是代码文档的重要组成部分,分为单行注释(以 //
开头)和多行注释(以 /*
开头并以 */
结尾),其中多行注释常用于包文档描述或注释成块的代码片段。单行注释与内容之间建议留一个空格。
每个包应有相关注释,package
语句前的块注释被视为包文档,应简要介绍包的功能和相关信息,如一个包可分散在多个文件中,只需在一个文件中添加包注释即可。所有全局作用域的类型、常量、变量、函数及导出的对象都应有合理注释,函数前的文档注释应以函数名开头(如 "Abcd..."
描述函数 Abcd
)。
标识符
在Go语言中,标识符(包括函数名、变量名、常量名、类型名、语句标号和包名等)的命名规则非常简单。每个标识符必须以字母(Unicode字母)或下划线开头,后续可以包含若干个字母、数字和下划线。需要注意的是,Go语言是区分大小写的,因此 heapSort
和 Heapsort
被视为两个不同的标识符。
虽然标识符的长度没有严格限制,但Go语言的风格倾向于使用简短的名字,尤其是对于局部变量。比如,常见的局部变量命名可能是 i
,而不是冗长的 theLoopIndex
。通常来说,如果一个名字的作用域比较大,生命周期也比较长,那么用长的名字将会更有意义。
此外,Go语言鼓励使用大小写混合的方式(如 MixedCaps
或 mixedCaps
)来命名,而避免使用下划线来连接多个单词。这样的命名方式使得代码更加简洁、易读且符合Go语言的命名约定。
下方列出所有的内置关键字:
break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var
此外,还有30多个预定义标识符,这些内部预先定义的名字并不是关键字,你可以在定义中重新使用它们:
/* 内建常量: true false iota nil 内建类型: int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float32 float64 complex64 complex128 uintptr bool byte rune string error 内建函数: make len cap new append copy close delete complex real imag panic recover */
_
本身就是一个特殊的标识符,被称为空白标识符。它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用这个标识符作为变量对其它变量进行赋值或运算。
一般代码结构
-
首先,完成该文件的
package
声明,import
导入所需的包。 -
然后对常量、变量和类型的定义或声明。
-
如果存在
init()
函数的话,则对该函数进行定义(这是一个特殊的函数,每个含有该函数的包都会首先执行这个函数)。 -
如果当前包是
main
包,则定义main()
函数。 -
然后定义其余的函数,首先是类型的方法,接着是按照
main()
函数中先后调用的顺序来定义相关函数,如果有很多函数,则可以按照字母顺序来进行排序。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通