1. 控制结构
Go语言的控制结构与Java类似,包括if、for和switch。这些结构在Go语言中非常简洁,且功能强大。
1.1 if语句
Go语言的if语句可以在条件表达式之前执行一个简单的语句。
package main
import "fmt"
func main() {
if x := 10; x > 5 {
fmt.Println("x is greater than 5")
} else {
fmt.Println("x is less than or equal to 5")
}
}
在这个例子中,x := 10是一个在if语句中定义的临时变量,只在if和else块中有效。
1.2 for循环
Go语言的for循环非常灵活,可以用来替代while循环。
package main
import "fmt"
func main() {
i := 0
for i < 5 {
fmt.Println(i)
i++
}
}
Go语言还支持传统的for循环结构。
for i := 0; i < 5; i++ {
fmt.Println(i)
}
1.3 switch语句
Go语言的switch语句比Java更加简洁,不需要break语句。
package main
import "fmt"
func main() {
day := "Monday"
switch day {
case "Monday":
fmt.Println("Today is Monday")
case "Tuesday":
fmt.Println("Today is Tuesday")
// 多个case
case "Saturday","Sunday":
fmt.Println("Today is Weekend")
default:
fmt.Println("Unknown day")
}
}
2. defer语句
defer语句用于延迟函数的执行,直到包含它的函数返回。这在资源管理和错误处理中非常有用。
package main
import "fmt"
func main() {
defer fmt.Println("World")
fmt.Println("Hello")
}
在这个例子中,defer fmt.Println("World")会在main函数返回之前执行,输出结果为:
Hello
World
defer语句常用于关闭文件、释放资源等操作。
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
//...
}
并且defer是遵循后进先出原则的,当有多个defer语句的时候,会优先执行最后一个defer语句。
3. channel和协程
Go语言的并发模型是其最大的亮点之一。通过goroutine和channel,Go语言可以轻松实现并发编程。
3.1 goroutine
goroutine是Go语言的轻量级线程,可以在函数调用前加上go关键字来启动一个goroutine。
package main
import (
"fmt"
"time"
)
func printNumbers() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
time.Sleep(time.Millisecond * 500)
}
}
func main() {
go printNumbers()
time.Sleep(time.Second * 3)
fmt.Println("Done")
}
在这个例子中,go printNumbers()启动了一个goroutine,time.Sleep(time.Second * 3)是为了让主程序等待goroutine执行完毕。
3.2 channel
channel是goroutine之间通信的机制,关键字为chan,是一种特殊的数据结构。
package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
ch <- 42
}()
value := <-ch
fmt.Println("Received:", value)
}
在这个例子中,ch := make(chan int)创建了一个int类型的channel,go func() { ch <- 42 }()启动了一个goroutine,向channel发送数据,value := <-ch从channel接收数据。
4. 包管理
Go语言的包管理与Java的import类似,但Go语言的包管理更加简洁。
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("Random number:", rand.Intn(100))
}
在这个例子中,import "math/rand"导入了math/rand包,rand.Intn(100)生成了一个0到99之间的随机数。
值得注意的是,在上一篇说到,每个go文件的init函数,在import的时候,会优先执行。
5. 错误处理
Go语言的错误处理机制与Java不同,Go语言鼓励函数返回错误值(向上返回),而不是抛出异常。
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("non_existent_file.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
// ...
}
在这个例子中,os.Open("non_existent_file.txt")返回一个文件句柄和一个错误值,如果文件不存在,err将不为nil,程序会打印错误信息并退出。
这里要吐槽一下,向上返回,真的就是if err != nil { return nil,err}
6. 总结与思考
Go语言的错误处理机制也与Java不同,Go语言鼓励函数返回错误值,而不是抛出异常。这种错误处理方式更加直观,但也需要程序员更加小心地处理错误。