一文了解golang关键字,gopher不多的记忆。

199 阅读11分钟

引言

我有一个刚开始学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 语句捕获不同通道中的结果。

两种可能的结果:

image.png image.png

代码中的关键字解释我将放在最后一部分,如果感兴趣,可以通过目录跳转。

25个关键字

Go 语言关键字(按字典序排列)

  1. break
  2. case
  3. chan
  4. const
  5. continue
  6. default
  7. defer
  8. else
  9. fallthrough
  10. for
  11. func
  12. go
  13. goto
  14. if
  15. import
  16. interface
  17. map
  18. package
  19. range
  20. return
  21. select
  22. struct
  23. switch
  24. type
  25. var

这些关键字构成了 Go 语言的核心,通过掌握这些基本元素,开发者可以高效构建出简洁且功能强大的程序。

break

break 用于立即终止循环或跳出 switch 语句。它在控制流程中非常重要,可以防止不必要的循环。

示例:

for i := 0; i < 10; i++ {
    if i == 5 {
        break // 循环到 i == 5 时终止
    }
    fmt.Println(i)
}

case

caseswitch 语句的一部分,表示一个匹配条件。如果表达式与 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

defaultswitch 语句中的一个选项,用于在没有匹配的 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

elseif-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 的简化版本。相比 ifswitch 更加清晰和简洁。

示例:

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 用于导入标准库或其他外部库。在这段代码中,导入了 fmtmath/randtime 包,分别用于格式化输出、生成随机数和处理时间。

3. const

const 用于声明常量。在代码中:

const IR = 3.14

IR 被定义为一个常量,它的值不会在程序运行时发生改变。常量在需要使用不变值时非常有用。

4. type

type 用于定义新类型。在代码中定义了两个类型:

type Account interface { ... }
type BankAccount struct { ... }
  • Account 是一个接口类型,定义了两个方法 DepositWithdraw,要求实现该接口的类型必须提供这两个方法。
  • BankAccount 是一个结构体,包含一个字段 balance 用于存储账户余额。

5. interface

interface 用于定义接口。在代码中,Account 接口定义了银行账户的两个行为:存款和取款。这使得任何类型都可以实现该接口,只要提供相应的方法。

6. struct

struct 用于定义结构体,结构体是 Go 中用于聚合数据的基本方式。在代码中:

type BankAccount struct {
    balance float64
}

BankAccount 是一个结构体,拥有一个字段 balance,表示账户余额。

7. func

func 用于定义函数和方法。在代码中,定义了多个函数,例如 DepositWithdrawmain 函数。方法是在结构体上绑定函数的方式,例如:

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. ifelse

ifelse 用于条件判断。在代码中:

if account.balance > 200 {
    fmt.Println("您的余额大于 200 元。")
} else {
    fmt.Println("您的余额小于或等于 200 元。")
}

这个条件判断账户余额是否大于 200 元,并根据结果输出不同的信息。

11. switchcase

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 用于从 chSuccesschFailure 通道中接收数据,并输出不同的结果。

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,输出每个人的账户余额。

声明

文章内容可能包含错误或不准确之处,若有发现,欢迎批评指正,感谢您的理解与支持!