引言
我有一个刚开始学C++的朋友,他抱怨道:“C++ 的关键字实在太多了,记都记不住!” ,写出来的代码显得十分陈旧,怎么都感受不到“高级感”,让他颇为痛苦。
我笑着说:“成为一名 Gopher 吧!十分钟记住 25 个关键字,轻松上手。”
本文将带你一次性掌握 Go 语言的关键字,轻松开启 Gopher 之路。
(编程语言各有千秋,此引言使用了夸张的修辞手法,仅供调侃!)
样例代码
通过这个百行样例代码,Gopher 们不仅能够掌握 Go 语言的常用关键字,还能通过实际的代码片段体验 Go 语言独有的简洁和强大。希望这些示例能帮助你轻松迈出学习 Go 的第一步。
有兴趣的同学,可以先阅读代码,猜一猜执行结果是否与自己的预期相符。即使你还没学过 Go 语言,也可以通过代码的逻辑进行推测,我想,你一定会推导出正确的结果。
如果有不理解的关键字,可以直接目录跳转,查看该关键字的功能,然后继续理解代码。
package main
import (
"fmt"
"math/rand"
"time"
)
// 定义一个常量,利率
const IR = 3.14
// 定义一个接口
type Account interface {
Deposit(amount float64)
Withdraw(amount float64)
}
// 定义一个结构体
type BankAccount struct {
balance float64
}
// 实现接口方法
func (ba *BankAccount) Deposit(amount float64) {
ba.balance += amount
fmt.Printf("存入金额: %.2f 元, 当前余额: %.2f 元\n", amount, ba.balance)
}
func (ba *BankAccount) Withdraw(amount float64) {
if ba.balance < amount {
fmt.Println("余额不足!")
return
}
ba.balance -= amount
fmt.Printf("取出金额: %.2f 元\n", amount)
}
func main() {
// 使用defer延迟执行,在函数返回前执行
defer fmt.Println("程序结束。")
// 使用const常量和接口
fmt.Printf("欢迎光临gopher银行,存款利率为: %.2f\n", IR)
// 使用var关键字定义变量
var account BankAccount
// 使用for循环
for i := 0; i < 3; i++ {
fmt.Print("for循环第", i+1, "次: ")
account.Deposit(100)
}
// 使用if-else条件控制
if account.balance > 200 {
fmt.Println("您的余额大于 200 元。")
} else {
fmt.Println("您的余额小于或等于 200 元。")
}
// 使用switch和case
switch account.balance {
case 300:
fmt.Println("余额正好是 300 元。")
fallthrough
default:
fmt.Println("请检查您的余额。")
}
// 使用select与chan进行并发通信
chSuccess := make(chan string) // 用于交易成功的通道
chFailure := make(chan string) // 用于交易失败的通道
randGen := rand.New(rand.NewSource(time.Now().UnixNano())) // 局部随机数生成器
// 检验select的用法,模拟交易过程
go func() {
transactionResult := randGen.Intn(2) // 随机生成0或1
time.Sleep(1 * time.Second) // 模拟交易过程的延迟
if transactionResult == 0 {
chSuccess <- "交易已完成"
} else {
chFailure <- "交易失败"
}
}()
// 使用select从两个通道中接收结果
select {
case msg := <-chSuccess:
fmt.Println(msg)
case msg := <-chFailure:
fmt.Println(msg)
}
// 使用goto跳转
goto End
End:
// 使用map数据结构
accounts := map[string]float64{
"Alice": 500,
"Bob": 150,
}
// 使用range遍历map
for name, balance := range accounts {
fmt.Printf("%s 的余额: %.2f 元\n", name, balance)
}
}
执行结果会有两种不同的情况,这是因为在 goroutine 中通过随机数生成器决定交易的成功或失败,并且由 select 语句捕获不同通道中的结果。
两种可能的结果:
代码中的关键字解释我将放在最后一部分,如果感兴趣,可以通过目录跳转。
25个关键字
Go 语言关键字(按字典序排列)
breakcasechanconstcontinuedefaultdeferelsefallthroughforfuncgogotoifimportinterfacemappackagerangereturnselectstructswitchtypevar
这些关键字构成了 Go 语言的核心,通过掌握这些基本元素,开发者可以高效构建出简洁且功能强大的程序。
break
break 用于立即终止循环或跳出 switch 语句。它在控制流程中非常重要,可以防止不必要的循环。
示例:
for i := 0; i < 10; i++ {
if i == 5 {
break // 循环到 i == 5 时终止
}
fmt.Println(i)
}
case
case 是 switch 语句的一部分,表示一个匹配条件。如果表达式与 case 中的值匹配,则执行相应的代码块。
示例:
switch day := 2; day {
case 1:
fmt.Println("星期一")
case 2:
fmt.Println("星期二")
default:
fmt.Println("其他")
}
chan
chan 用于声明通道(channel),这是 Go 中用于并发通信的核心机制。通过通道可以在线程之间传递数据。
示例:
messages := make(chan string)
go func() {
messages <- "Hello, Gopher!" // 发送数据到通道
}()
msg := <-messages // 从通道接收数据
fmt.Println(msg)
const
const 用于声明常量,常量的值在程序运行时不能更改。
示例:
const Pi = 3.14
fmt.Println("Pi 的值为:", Pi)
continue
continue 用于跳过当前循环的剩余代码,直接开始下一次循环。
示例:
for i := 0; i < 10; i++ {
if i%2 == 0 {
continue // 跳过偶数的输出
}
fmt.Println(i)
}
default
default 是 switch 语句中的一个选项,用于在没有匹配的 case 时执行。
示例:
switch day := 3; day {
case 1:
fmt.Println("星期一")
case 2:
fmt.Println("星期二")
default:
fmt.Println("其他")
}
defer
defer 用于延迟执行某个函数,通常用于确保资源在使用后被释放。
示例:
func main() {
defer fmt.Println("程序结束") // 程序退出时输出
fmt.Println("程序运行中")
}
else
else 是 if-else 语句的一部分,用于在 if 条件不满足时执行另一个代码块。
示例:
if x := 5; x > 10 {
fmt.Println("x 大于 10")
} else {
fmt.Println("x 小于等于 10")
}
fallthrough
fallthrough 用于强制 switch 语句继续执行下一个 case,即使条件不匹配。
示例:
switch i := 1; i {
case 1:
fmt.Println("第一项")
fallthrough
case 2:
fmt.Println("第二项")
default:
fmt.Println("默认")
}
for
for 是 Go 中唯一的循环控制结构,适用于迭代、条件控制等多种场景。
示例:
for i := 0; i < 5; i++ {
fmt.Println(i)
}
func
func 用于声明函数,这是 Go 语言中的基础结构。
示例:
func add(a int, b int) int {
return a + b
}
result := add(3, 4)
fmt.Println("结果为:", result)
go
go 关键字用于启动一个新的 goroutine,实现并发操作。Go 的并发性非常强大,goroutine 是其核心概念之一。
示例:
go func() {
fmt.Println("这是一个新的 goroutine")
}()
goto
goto 用于无条件跳转到程序中的某个标签。虽然不推荐频繁使用,但在某些场景下可以简化代码。
示例:
func main() {
i := 0
Start:
if i < 5 {
fmt.Println(i)
i++
goto Start // 跳转到 Start 标签处
}
}
if
if 是条件判断语句,用于根据布尔表达式的值执行不同的代码块。
示例:
if x := 10; x > 5 {
fmt.Println("x 大于 5")
}
import
import 用于导入外部包或库。通过导入不同的包,可以扩展程序的功能。
示例:
import "fmt"
interface
interface 用于定义接口,接口是 Go 语言实现多态的核心概念。通过接口,可以定义一组行为,而不关注具体的实现。
示例:
type Speaker interface {
Speak()
}
type Dog struct{}
func (d Dog) Speak() {
fmt.Println("汪汪!")
}
var s Speaker = Dog{}
s.Speak()
map
map 是 Go 中的一种数据结构,用于存储键值对。它非常适合用于快速查找。
示例:
m := map[string]int{
"Alice": 25,
"Bob": 30,
}
fmt.Println("Alice 的年龄:", m["Alice"])
package
package 是 Go 语言的基本代码组织单位。每个 Go 文件都必须属于一个包,main 包是程序的入口点。
示例:
package main
func main() {
fmt.Println("这是主程序包")
}
range
range 用于遍历数组、切片、map 或通道。在循环中可以获得键和值。
示例:
numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
fmt.Println("索引:", index, "值:", value)
}
return
return 用于从函数中返回值,并终止函数的执行。
示例:
func add(a int, b int) int {
return a + b
}
result := add(3, 4)
fmt.Println("结果:", result)
select
select 用于处理多个通道的发送和接收操作,是 Go 并发模型中非常重要的特性。
示例:
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
ch1 <- "来自通道1的数据"
}()
go func() {
ch2 <- "来自通道2的数据"
}()
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
}
struct
struct 用于定义结构体,是 Go 语言中用于聚合数据的一种重要类型。通过结构体,可以将不同类型的数据组合在一起。
示例:
type Person struct {
Name string
Age int
}
p := Person{Name: "Alice", Age: 30}
fmt.Println(p.Name, "的年龄是", p.Age)
switch
switch 用于多分支选择,类似于多个 if-else 的简化版本。相比 if,switch 更加清晰和简洁。
示例:
switch x := 2; x {
case 1:
fmt.Println("x 等于 1")
case 2:
fmt.Println("x 等于 2")
default:
fmt.Println("x 是其他值")
}
type
type 用于定义新类型,可以是结构体、接口或者其他类型的别名。
示例:
type Age int
var myAge Age = 30
fmt.Println("我的年龄是", myAge)
var
var 用于声明变量,可以显式地指定类型,也可以让编译器推断类型。
示例:
var name string = "Alice"
var age = 30
fmt.Println(name, "的年龄是", age)
样例代码中关键字解释
在这段 Go 代码中,使用了多个 Go 语言的关键字,下面将详细解释这些关键字的功能和用法:
1. package
package 用于声明该文件属于哪个包。在 Go 中,main 包是程序的入口点。必须包含 package main 以及一个 main() 函数,程序才能运行。
2. import
import 用于导入标准库或其他外部库。在这段代码中,导入了 fmt、math/rand 和 time 包,分别用于格式化输出、生成随机数和处理时间。
3. const
const 用于声明常量。在代码中:
const IR = 3.14
IR 被定义为一个常量,它的值不会在程序运行时发生改变。常量在需要使用不变值时非常有用。
4. type
type 用于定义新类型。在代码中定义了两个类型:
type Account interface { ... }
type BankAccount struct { ... }
Account是一个接口类型,定义了两个方法Deposit和Withdraw,要求实现该接口的类型必须提供这两个方法。BankAccount是一个结构体,包含一个字段balance用于存储账户余额。
5. interface
interface 用于定义接口。在代码中,Account 接口定义了银行账户的两个行为:存款和取款。这使得任何类型都可以实现该接口,只要提供相应的方法。
6. struct
struct 用于定义结构体,结构体是 Go 中用于聚合数据的基本方式。在代码中:
type BankAccount struct {
balance float64
}
BankAccount 是一个结构体,拥有一个字段 balance,表示账户余额。
7. func
func 用于定义函数和方法。在代码中,定义了多个函数,例如 Deposit、Withdraw 和 main 函数。方法是在结构体上绑定函数的方式,例如:
func (ba *BankAccount) Deposit(amount float64) { ... }
这个方法定义了如何对 BankAccount 进行存款操作。
8. var
var 用于声明变量。在代码中,声明了 account 变量:
var account BankAccount
它声明了一个类型为 BankAccount 的变量 account。
9. for
for 是 Go 中的循环结构,用于迭代执行代码。在代码中:
for i := 0; i < 3; i++ {
fmt.Print("for循环第", i+1, "次: ")
account.Deposit(100)
}
这个 for 循环重复执行 3 次,每次向账户中存入 100 元。
10. if 和 else
if 和 else 用于条件判断。在代码中:
if account.balance > 200 {
fmt.Println("您的余额大于 200 元。")
} else {
fmt.Println("您的余额小于或等于 200 元。")
}
这个条件判断账户余额是否大于 200 元,并根据结果输出不同的信息。
11. switch 和 case
switch 用于条件匹配,case 表示每个匹配条件。在代码中:
switch account.balance {
case 300:
fmt.Println("余额正好是 300 元。")
fallthrough
default:
fmt.Println("请检查您的余额。")
}
这个 switch 语句检查账户余额,并在匹配 300 时输出相应的消息。
12. fallthrough
fallthrough 用于强制执行下一个 case。即使余额为 300,程序会在输出 "余额正好是 300 元" 后继续执行 default 分支。
13. defer
defer 用于延迟执行某个函数,直到包含 defer 的函数返回时才执行。在代码中:
defer fmt.Println("程序结束。")
这会在 main() 函数结束时输出 "程序结束。",通常用于释放资源或完成收尾工作。
14. go
go 关键字用于启动一个新的 goroutine,Go 中的并发是通过 goroutine 实现的。在代码中:
go func() { ... }()
启动了一个 goroutine 来模拟异步的交易结果。
15. select
select 用于多路复用通道操作。它可以从多个通道中接收值。在代码中:
select {
case msg := <-chSuccess:
fmt.Println(msg)
case msg := <-chFailure:
fmt.Println(msg)
}
select 用于从 chSuccess 或 chFailure 通道中接收数据,并输出不同的结果。
16. chan
chan 用于声明通道,通道是 Go 中用于在 goroutine 之间进行通信的机制。在代码中:
chSuccess := make(chan string)
chFailure := make(chan string)
定义了两个字符串类型的通道,用于接收交易的结果。
17. goto
goto 用于无条件跳转到指定的标签。在代码中:
goto End
End:
程序执行到 goto End 时会跳转到标签 End,通常在非常规控制流场景下使用,但不推荐频繁使用。
18. map
map 是 Go 中的一种数据结构,用于存储键值对。在代码中:
accounts := map[string]float64{
"Alice": 500,
"Bob": 150,
}
定义了一个 map,存储账户持有人及其余额。
19. range
range 用于遍历数组、切片、map 或通道。在代码中:
for name, balance := range accounts {
fmt.Printf("%s 的余额: %.2f 元\n", name, balance)
}
range 用于遍历 map,输出每个人的账户余额。
声明
文章内容可能包含错误或不准确之处,若有发现,欢迎批评指正,感谢您的理解与支持!