Go语言基础入门指南
前言
Go语言(也称为Golang)是Google开发的一种静态强类型、编译型语言。自2009年发布以来,Go凭借其简洁的语法、出色的并发性能和快速的编译速度,在云计算、微服务、区块链等领域得到了广泛应用。
为什么选择Go语言?
1. 语言特性优势
- 简洁易学:语法简单,关键字仅25个
- 高性能:编译型语言,接近C语言的执行效率
- 并发友好:原生支持goroutine和channel
- 快速编译:编译速度极快,提升开发效率
- 内存安全:自动垃圾回收,避免内存泄漏
2. 生态系统完善
1 2 3 4 5
| go mod init myproject go get github.com/gin-gonic/gin go build go run main.go
|
Go语言基础语法
1. 环境搭建
安装Go
1 2 3 4 5 6 7 8 9 10 11
| brew install go
wget https://golang.org/dl/go1.21.0.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin export GOPATH=$HOME/go export GOROOT=/usr/local/go
|
验证安装
2. Hello World程序
1 2 3 4 5 6 7
| package main
import "fmt"
func main() { fmt.Println("Hello, World!") }
|
1 2 3 4 5
| go run main.go
go build main.go ./main
|
3. 基本数据类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package main
import "fmt"
func main() { var name string = "Go语言" var age int = 15 var isActive bool = true var score float64 = 98.5 language := "Golang" year := 2009 const PI = 3.14159 const MaxUsers = 1000 fmt.Printf("语言: %s, 年龄: %d岁, 活跃: %t, 评分: %.1f\n", name, age, isActive, score) fmt.Printf("别名: %s, 发布年份: %d\n", language, year) }
|
4. 数组和切片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package main
import "fmt"
func main() { var numbers [5]int = [5]int{1, 2, 3, 4, 5} languages := [3]string{"Go", "Python", "Java"} slice := []int{10, 20, 30, 40, 50} slice = append(slice, 60, 70) subSlice := slice[1:4] fmt.Println("数组:", numbers) fmt.Println("语言:", languages) fmt.Println("切片:", slice) fmt.Println("子切片:", subSlice) for i, v := range slice { fmt.Printf("索引: %d, 值: %d\n", i, v) } }
|
5. 映射(Map)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package main
import "fmt"
func main() { userAges := make(map[string]int) userAges["Alice"] = 25 userAges["Bob"] = 30 userAges["Charlie"] = 35 scores := map[string]int{ "数学": 95, "英语": 88, "物理": 92, } age, exists := userAges["Alice"] if exists { fmt.Printf("Alice的年龄: %d\n", age) } for subject, score := range scores { fmt.Printf("%s: %d分\n", subject, score) } delete(userAges, "Bob") fmt.Println("删除Bob后:", userAges) }
|
函数和方法
1. 函数定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package main
import "fmt"
func add(a, b int) int { return a + b }
func divide(a, b float64) (float64, error) { if b == 0 { return 0, fmt.Errorf("除数不能为零") } return a / b, nil }
func calculate(a, b int) (sum, product int) { sum = a + b product = a * b return }
func sum(numbers ...int) int { total := 0 for _, num := range numbers { total += num } return total }
func main() { fmt.Println("加法:", add(3, 5)) result, err := divide(10, 3) if err != nil { fmt.Println("错误:", err) } else { fmt.Printf("除法结果: %.2f\n", result) } s, p := calculate(4, 6) fmt.Printf("和: %d, 积: %d\n", s, p) fmt.Println("求和:", sum(1, 2, 3, 4, 5)) }
|
2. 结构体和方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| package main
import "fmt"
type Person struct { Name string Age int City string }
func (p Person) Introduce() string { return fmt.Sprintf("我是%s,今年%d岁,来自%s", p.Name, p.Age, p.City) }
func (p *Person) HaveBirthday() { p.Age++ }
func NewPerson(name, city string, age int) *Person { return &Person{ Name: name, Age: age, City: city, } }
func main() { person1 := Person{ Name: "张三", Age: 25, City: "北京", } person2 := NewPerson("李四", "上海", 30) fmt.Println(person1.Introduce()) fmt.Println(person2.Introduce()) person1.HaveBirthday() fmt.Printf("%s现在%d岁了\n", person1.Name, person1.Age) }
|
接口和多态
1. 接口定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| package main
import "fmt"
type Shape interface { Area() float64 Perimeter() float64 }
type Rectangle struct { Width, Height float64 }
func (r Rectangle) Area() float64 { return r.Width * r.Height }
func (r Rectangle) Perimeter() float64 { return 2 * (r.Width + r.Height) }
type Circle struct { Radius float64 }
func (c Circle) Area() float64 { return 3.14159 * c.Radius * c.Radius }
func (c Circle) Perimeter() float64 { return 2 * 3.14159 * c.Radius }
func PrintShapeInfo(s Shape) { fmt.Printf("面积: %.2f, 周长: %.2f\n", s.Area(), s.Perimeter()) }
func main() { rect := Rectangle{Width: 5, Height: 3} circle := Circle{Radius: 4} fmt.Println("矩形信息:") PrintShapeInfo(rect) fmt.Println("圆形信息:") PrintShapeInfo(circle) shapes := []Shape{rect, circle} for i, shape := range shapes { fmt.Printf("形状%d: ", i+1) PrintShapeInfo(shape) } }
|
并发编程
1. Goroutine基础
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package main
import ( "fmt" "time" )
func sayHello(name string) { for i := 0; i < 3; i++ { fmt.Printf("Hello, %s! (%d)\n", name, i+1) time.Sleep(100 * time.Millisecond) } }
func main() { go sayHello("Alice") go sayHello("Bob") time.Sleep(500 * time.Millisecond) fmt.Println("程序结束") }
|
2. Channel通信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package main
import ( "fmt" "time" )
func producer(ch chan<- int) { for i := 1; i <= 5; i++ { fmt.Printf("生产: %d\n", i) ch <- i time.Sleep(100 * time.Millisecond) } close(ch) }
func consumer(ch <-chan int) { for value := range ch { fmt.Printf("消费: %d\n", value) time.Sleep(200 * time.Millisecond) } }
func main() { ch := make(chan int, 2) go producer(ch) go consumer(ch) time.Sleep(2 * time.Second) }
|
3. Select语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package main
import ( "fmt" "time" )
func main() { ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(100 * time.Millisecond) ch1 <- "来自channel1的消息" }() go func() { time.Sleep(200 * time.Millisecond) ch2 <- "来自channel2的消息" }() for i := 0; i < 2; i++ { select { case msg1 := <-ch1: fmt.Println("收到:", msg1) case msg2 := <-ch2: fmt.Println("收到:", msg2) case <-time.After(300 * time.Millisecond): fmt.Println("超时") } } }
|
错误处理
1. 基本错误处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package main
import ( "errors" "fmt" )
func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("除数不能为零") } return a / b, nil }
func main() { result, err := divide(10, 0) if err != nil { fmt.Println("错误:", err) return } fmt.Println("结果:", result) }
|
2. 自定义错误类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| package main
import "fmt"
type ValidationError struct { Field string Message string }
func (e ValidationError) Error() string { return fmt.Sprintf("验证错误 - %s: %s", e.Field, e.Message) }
func validateAge(age int) error { if age < 0 { return ValidationError{ Field: "age", Message: "年龄不能为负数", } } if age > 150 { return ValidationError{ Field: "age", Message: "年龄不能超过150岁", } } return nil }
func main() { ages := []int{25, -5, 200} for _, age := range ages { if err := validateAge(age); err != nil { fmt.Printf("年龄 %d: %s\n", age, err) } else { fmt.Printf("年龄 %d: 有效\n", age) } } }
|
实战项目:简单Web服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| package main
import ( "encoding/json" "fmt" "log" "net/http" "strconv" "time" )
type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` CreateAt time.Time `json:"created_at"` }
var users []User var nextID = 1
func main() { users = append(users, User{ ID: nextID, Name: "张三", Email: "zhangsan@example.com", CreateAt: time.Now(), }) nextID++ http.HandleFunc("/users", handleUsers) http.HandleFunc("/users/", handleUserByID) http.HandleFunc("/health", handleHealth) fmt.Println("服务器启动在 :8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
func handleUsers(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": getUsersHandler(w, r) case "POST": createUserHandler(w, r) default: http.Error(w, "方法不允许", http.StatusMethodNotAllowed) } }
func getUsersHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(users) }
func createUserHandler(w http.ResponseWriter, r *http.Request) { var user User if err := json.NewDecoder(r.Body).Decode(&user); err != nil { http.Error(w, "无效的JSON", http.StatusBadRequest) return } user.ID = nextID user.CreateAt = time.Now() nextID++ users = append(users, user) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(user) }
func handleUserByID(w http.ResponseWriter, r *http.Request) { idStr := r.URL.Path[len("/users/"):] id, err := strconv.Atoi(idStr) if err != nil { http.Error(w, "无效的用户ID", http.StatusBadRequest) return } for _, user := range users { if user.ID == id { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) return } } http.Error(w, "用户未找到", http.StatusNotFound) }
func handleHealth(w http.ResponseWriter, r *http.Request) { response := map[string]string{ "status": "healthy", "time": time.Now().Format(time.RFC3339), } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) }
|
学习路径建议
1. 基础阶段(1-2周)
- ✅ 掌握基本语法和数据类型
- ✅ 理解函数和方法
- ✅ 学习结构体和接口
2. 进阶阶段(2-3周)
- 🔧 深入学习并发编程
- 🔧 掌握错误处理模式
- 🔧 学习包管理和模块系统
3. 实战阶段(3-4周)
- 🚀 构建Web应用
- 🚀 学习数据库操作
- 🚀 掌握测试和部署
常用工具和库
1. Web框架
1 2 3 4 5
| go get github.com/gin-gonic/gin
go get github.com/labstack/echo/v4
|
2. 数据库
1 2 3 4 5 6
| go get gorm.io/gorm go get gorm.io/driver/mysql
go get github.com/go-redis/redis/v8
|
3. 工具库
1 2 3 4 5 6 7 8
| go get github.com/google/uuid
go get github.com/spf13/viper
go get github.com/sirupsen/logrus
|
总结
Go语言以其简洁的语法、强大的并发能力和优秀的性能,成为现代软件开发的重要选择。通过本指南的学习,你应该能够:
- ✅ 掌握Go语言的基本语法和特性
- ✅ 理解Go的并发编程模型
- ✅ 能够构建简单的Web应用
- ✅ 具备继续深入学习的基础
下一步学习建议
- 深入并发编程:学习更复杂的并发模式
- 微服务开发:使用Go构建微服务架构
- 性能优化:学习Go程序的性能调优
- 开源贡献:参与Go社区的开源项目
Go语言的学习之路才刚刚开始,持续实践和探索将帮助你成为优秀的Go开发者!
本文涵盖了Go语言的核心概念和实战应用,希望能帮助你快速入门Go语言开发。如有疑问,欢迎交流讨论!