1. 变量与常量
在 Go 中,变量使用 var
声明,常量使用 const
声明。
var name = "Alice" // 变量
const age = 30 // 常量
注意事项:常量的值在编译时必须确定,变量可以使用短变量声明 :=
。
2. 数据类型
Go 中的基础数据类型包括 int
、float64
、string
和 bool
。
var height float64 = 1.75
var isStudent bool = true
易错点:Go 是强类型语言,不同类型之间不能直接转换。
3. 条件语句
Go 中的条件语句有 if
、else
和 switch
。
if age > 18 {
fmt.Println("Adult")
} else {
fmt.Println("Minor")
}
注意事项:Go 中的条件不需要圆括号,if
语句中可以声明变量。
4. 循环
Go 只有 for
循环,没有 while
循环。for
可以实现条件、无限和范围循环。
for i := 0; i < 5; i++ {
fmt.Println(i)
}
易错点: for
循环的条件为空时即为无限循环。
5. 函数
使用 func
定义函数,支持多个返回值。
func add(a int, b int) int {
return a + b
}
注意事项:Go 函数参数类型定义可以合并,例如 func add(a, b int)
。
6. 结构体与接口
Go 支持结构体定义数据类型,接口用于定义行为。
type Person struct {
Name string
Age int
}
type Describer interface {
Describe() string
}
注意事项:接口是隐式实现的,任何类型只要实现接口的方法就实现了该接口。
7. 方法
方法可以定义在结构体上,使用指针接收器以允许修改。
func (p *Person) UpdateAge(newAge int) {
p.Age = newAge
}
注意事项:方法的接收器类型定义时要一致,使用指针接收器以避免值传递。
8. 并发与 Goroutine
使用 go
关键字启动 goroutine,并使用通道(channel)进行数据通信。
func printNumber() {
fmt.Println("Hello from goroutine!")
}
func main() {
go printNumber()
}
注意事项:goroutine 之间的数据传递应通过 channel 进行,避免数据竞争。
9. 错误处理
Go 使用返回值而非异常处理错误,推荐模式是 if err != nil
。
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
注意事项:Go 中没有 try-catch
,错误处理需显式处理。
高级与小众用法
延迟执行 (defer)
使用 defer
延迟函数执行直到当前函数返回,通常用于资源释放。
func main() {
defer fmt.Println("This will print last.")
fmt.Println("This will print first.")
}
易错点:defer
按逆序执行,因此多个 defer
会按声明顺序倒序执行。
空白标识符 (_)
Go 中的 _
是空白标识符,用于忽略不需要的返回值。
result, _ := someFunction()
注意事项:空白标识符仅能忽略值,不会释放内存。
标签与跳转
Go 支持标签和 goto
,用于在代码中跳转。
func main() {
for i := 0; i < 5; i++ {
if i == 3 {
goto Skip
}
fmt.Println(i)
}
Skip:
fmt.Println("Jumped to label")
}
注意事项:避免滥用 goto
,以免导致代码难以阅读和维护。
类型断言
类型断言用于将接口转换为具体类型。
var i interface{} = "hello"
str, ok := i.(string)
if ok {
fmt.Println("i is a string:", str)
}
易错点:类型断言失败会引发 panic,使用 , ok
检查更安全。
匿名函数与闭包
Go 支持匿名函数和闭包,可用于即用即弃的函数。
func main() {
add := func(a, b int) int { return a + b }
fmt.Println(add(2, 3))
}
注意事项:闭包可以捕获外部变量,但可能导致意外的变量修改。
select 语句
select
用于从多个 channel 中选择一个进行通信。
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() { c1 <- "from c1" }()
go func() { c2 <- "from c2" }()
select {
case msg1 := <-c1:
fmt.Println(msg1)
case msg2 := <-c2:
fmt.Println(msg2)
}
}
注意事项:所有 case 都不准备好时,select 会阻塞,可以使用 default
防止阻塞。