本文深入探讨了 Go 编程语言中的外围概念,包含标识符、关键字、具名函数、具名值、定义类型、类型别名、包和模块治理,以及代码块和断行。这些元素是形成 Go 程序的根底,也是编写高质量代码的要害。
关注 TechLeadCloud,分享互联网架构、云服务技术的全维度常识。作者领有 10+ 年互联网服务架构、AI 产品研发教训、团队治理教训,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收 AI 产品研发负责人。
在 Go 编程中,代码元素是构建软件的根底。本文旨在深入探讨 Go 语言中的各种代码元素,包含函数、变量、类型和更多。咱们还会波及如何通过包(package)来组织这些元素,以及 Go 的关键字和标识符规定。
标识符与关键字
在任何编程语言中,标识符和关键字都是外围概念,Go 也不例外。标识符用于命名各种类型的代码元素,如变量、常量、函数等。关键字是预留的词汇,用于批示编程语言的特定操作。在本局部中,咱们将具体介绍 Go 语言中的标识符和关键字。
Go 中的标识符
标识符是用于标识各种程序实体(例如变量、函数、类型等)的名称。在 Go 中,标识符遵循以下规定:
- 必须以字母或下划线(
_
)结尾。 - 能够蕴含字母、数字和下划线(
_
)。 - 辨别大小写。
例如,以下都是无效的 Go 标识符:
name
_x9
go_variable
Count123
以下是有效的标识符:
9name // 以数字结尾
!var // 蕴含非法字符
Go 关键字
Go 语言有 25 个预留的关键字,不能用作标识符。以下是这些关键字的列表以及它们的简要解释:
break 用于中断循环或 switch 语句
default 用于 switch 语句,示意默认状况
func 定义新的函数
interface 定义接口
select 用于解决多个通道
case 用于 switch 和 select 语句中的条件分支
defer 用于确保函数调用在程序执行完结后产生
go 用于并发执行
map 定义 map 类型
struct 定义构造体
chan 定义通道类型
else 用于 if-else 构造
goto 用于无条件跳转
package 定义包
switch 用于多路分支
const 定义常量或常量组
fallthrough 用于 switch 语句,使得控制流穿透到下一个 case
if 条件语句
range 用于循环遍历数组、切片、字符串、map 或通道
type 定义新的数据类型或类型别名
continue 跳过以后循环的残余局部,开始下一次迭代
for 循环语句
import 导入包
return 从函数返回
var 申明变量
关键字示例
// 应用 if-else 关键字
if x > 10 {fmt.Println("x is greater than 10")
} else {fmt.Println("x is not greater than 10")
}
// 应用 for 关键字
for i := 0; i < 5; i++ {fmt.Println(i)
}
// 应用 func 和 return 关键字
func add(a int, b int) int {return a + b}
具名的函数
在 Go 语言中,函数是一组执行特定工作的代码块,具名函数即是有名称的函数。本文将具体探讨 Go 中各类具名函数,包含惯例函数、办法、高阶函数、匿名函数和闭包。
惯例函数
这是最根底的函数类型。惯例函数具备名称,能够承受参数,并且能够返回值。
代码示例
// 惯例函数,承受两个 int 类型参数,返回 int 类型值
func add(a int, b int) int {return a + b}
办法
在 Go 中,办法是一种非凡类型的函数,它作用于特定类型的变量,这个特定类型称为接收者。
代码示例
type Circle struct {Radius float64}
// Circle 类型的办法,计算圆的面积
func (c Circle) Area() float64 {return 3.14159 * c.Radius * c.Radius}
高阶函数
高阶函数是承受函数作为参数或返回一个函数的函数。
代码示例
// 高阶函数,承受一个函数作为参数
func applyFunc(f func(int) int, value int) int {return f(value)
}
匿名函数与 Lambda 表达式
匿名函数是没有名字的函数,通常用于长期操作。
代码示例
// 匿名函数
add := func(a, b int) int {return a + b}
闭包
闭包是一个函数值,它援用了其函数体之外的变量。简略来说,这个函数“记住了”这些援用的变量。
代码示例
// 闭包示例
func outer() func() int {
x := 0
return func() int {
x++
return x
}
}
具名的值
在 Go 语言中,具名的值次要包含变量和常量。这些都是用于存储数据或代表特定值的标识符。接下来,咱们会别离探讨变量和常量的各种类型和用法。
变量
变量是用于存储数据的容器。在 Go 中,变量的申明有多种形式,并且反对多种数据类型。
根本数据类型
Go 反对一系列根本的数据类型,包含整数、浮点数、布尔值、字符串等。
var i int = 10 // 整数
var f float64 = 10.5 // 浮点数
var b bool = true // 布尔值
var s string = "hello" // 字符串
复合数据类型
Go 还提供了数组、切片、映射(Map)、构造体(Struct)等复合数据类型。
var arr [3]int = [3]int{1, 2, 3} // 数组
var slice []int = []int{1, 2, 3} // 切片
var m map[string]int = map[string]int{"a": 1, "b": 2} // 映射
type Person struct {Name string; Age int} // 构造体
指针类型
Go 语言也反对指针,但不反对指针运算。
var p *int
i := 42
p = &i
常量
与变量不同,常量是不可变的值,一旦申明,就不能更改。
根本常量类型
const pi float64 = 3.14159 // 浮点数常量
const str string = "Hello" // 字符串常量
const b bool = true // 布尔常量
枚举常量
在 Go 中,能够应用 iota
关键字生成一组增量的整数常量,通常用于枚举。
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
)
常量表达式
Go 反对常量表达式,容许用于计算的常量值在编译期间进行运算。
const x = 2 + 3
定义类型和类型别名
Go 语言不仅提供了一系列内建类型,还容许通过 type
关键字定义新的类型或为现有的类型创立别名。这两者在语法上可能类似,但在类型零碎中有不同的意义和用处。本篇文章旨在具体介绍定义类型和类型别名的各种状况。
类型定义(Type Definition)
通过类型定义,你能够创立一个全新的类型,只管它可能与某个现有类型在结构上完全相同。
根底类型
上面是如何定义一个基于 int
的新类型MyInt
:
type MyInt int
复合类型
也能够基于复合类型来定义新类型:
type MyMap map[string]int
type Person struct {
Name string
Age int
}
接口类型
你还能够定义接口类型,它蕴含了一组办法签名:
type Writer interface {Write([]byte) (int, error)
}
类型别名(Type Alias)
类型别名并不创立新类型,只是为现有类型创立一个新名字。
type Integer = int
类型定义与类型别名的区别
类型定义和类型别名在 Go 中有着实质的区别。
- 类型定义会创立一个全新的类型,它与其根底类型在类型零碎中是齐全不同的。
- 类型别名只是创立了一个新名称,但并没有创立新类型。
代码示例
type MyInt int
type YourInt = int
var a int
var b MyInt
var c YourInt
a = 1
b = MyInt(a) // 须要显式转换
c = a // 不须要转换,因为 YourInt 只是 int 的别名
包和模块治理
Go 语言通过包(Packages)和模块(Modules)来组织和治理代码。这两者尽管在目标上有些许类似,但在用法和规模上各有特点。在本篇文章中,咱们将深入探讨 Go 中的包和模块治理,以及如何高效地应用它们。
包(Packages)
包是 Go 语言代码组织的根本单位。每个 Go 程序都是由包组成的,包用于封装代码以实现可重用和可保护。
规范库包
Go 语言提供了丰盛的规范库,例如 fmt
, net/http
, io
等。
import "fmt"
func main() {fmt.Println("Hello, world!")
}
自定义包
你也能够创立自定义的包。通常状况下,每个文件夹就是一个独自的包。
例如,创立一个名为 mathutils
的包:
// mathutils/add.go
package mathutils
func Add(a, b int) int {return a + b}
应用自定义包:
import "mathutils"
func main() {sum := mathutils.Add(1, 2)
}
包的可见性
在 Go 中,以大写字母结尾的函数或变量在包外是可见的(Public),以小写字母结尾的则不是(Private)。
模块(Modules)
模块是包的汇合。Go 1.11 版本引入了模块的概念,旨在解决依赖治理问题。
初始化模块
应用 go mod init
初始化一个新模块。
go mod init mymodule
这将生成一个 go.mod
文件,其中列出了模块名和依赖。
增加依赖
当你导入一个新的包并运行 go build
或 go get
,依赖将主动增加到 go.mod
文件。
降级和降级依赖
你能够应用 go get
命令降级或降级模块依赖。
go get -u example.com/some/module@v1.2.3
代码块与断行
在 Go 编程中,了解如何无效地应用代码块和断行是编写可读、可保护代码的根底。在本篇文章中,咱们将深刻理解 Go 语言中各种类型的代码块和断行规定。
代码块(Code Blocks)
代码块是由一对大括号 {}
突围的代码序列。这些代码块在不同的语境中有不同的作用。
函数体
最常见的代码块是函数体,它蕴含函数的实现。
func sayHello() {fmt.Println("Hello!")
}
控制结构
if
、for
、switch
等控制结构也应用代码块。
if true {fmt.Println("This is true.")
}
for i := 0; i < 3; i++ {fmt.Println(i)
}
申明块
常量和变量也能够在块内申明。
const (
Pi = 3.14
E = 2.71
)
断行(Line Breaks)
Go 语言绝对宽松的断行规定让你能够在少数表达式和申明中自在地增加空白和换行。
语句完结
在 Go 中,大多数语句通过换行符或者分号来完结。
fmt.Println("This is the end of the statement")
长语句的断行
对于较长的语句,Go 容许在操作符左近断行。
result := someVeryLongVariable +
anotherVeryLongVariable -
yetAnotherVeryLongVariable
函数调用和定义
在函数调用或定义时,参数也能够进行断行。
func longFunction(
param1 int,
param2 string,
param3 float64,
) {// 函数体}
总结
通过深入探讨 Go 语言的标识符、关键字、具名函数、具名值、定义类型、类型别名、包和模块治理,以及代码块和断行,本系列文章旨在提供一个全面且深刻的视角来了解 Go 编程的各个方面。这些元素独特形成了 Go 语言的基础架构,熟练掌握它们是编写可保护、高效和可扩大代码的要害。心愿这些内容可能帮忙你在 Go 编程路线上更进一步,敬请期待咱们接下来更多的深刻文章和教程。
关注 TechLeadCloud,分享互联网架构、云服务技术的全维度常识。作者领有 10+ 年互联网服务架构、AI 产品研发教训、团队治理教训,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收 AI 产品研发负责人。
如有帮忙,请多关注
集体微信公众号:【TechLeadCloud】分享 AI 与云服务研发的全维度常识,谈谈我作为 TechLead 对技术的独特洞察。
TeahLead KrisChang,10+ 年的互联网和人工智能从业教训,10 年 + 技术和业务团队治理教训,同济软件工程本科,复旦工程治理硕士,阿里云认证云服务资深架构师,上亿营收 AI 产品业务负责人。