1. Go语言概述
Go语言(简称Go)是Google开发的一种静态强类型、编译型语言,具有垃圾回收、并发编程、内存安全等特性。Go语言设计简洁,语法清晰,适合构建高性能、高并发的后端服务。更多学习教程www.fgedu.net.cn
2. Go开发环境搭建
搭建Go开发环境需要安装Go编译器和相关工具。
# 1. 下载Go安装包
$ wget https://go.dev/dl/go1.20.10.linux-amd64.tar.gz
# 2. 解压到/usr/local目录
$ sudo tar -C /usr/local -xzf go1.20.10.linux-amd64.tar.gz
# 3. 配置环境变量
$ vi ~/.bashrc
# 添加以下内容
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
# 使环境变量生效
$ source ~/.bashrc
# 4. 验证安装
$ go version
go version go1.20.10 linux/amd64
# 5. 创建工作目录
$ mkdir -p $GOPATH/src $GOPATH/pkg $GOPATH/bin
# 6. 测试Go环境
$ cat > $GOPATH/src/hello.go << 'EOF'
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
}
EOF
# 7. 编译并运行
$ go run $GOPATH/src/hello.go
Hello, Go!
# 8. 安装Go模块
$ go get github.com/gin-gonic/gin
3. Go基础知识
Go语言的基础知识包括变量、数据类型、运算符、控制语句等。学习交流加群风哥微信: itpux-com
package main
import “fmt”
func main() {
// 变量声明与赋值
var name string = “Go Developer”
var age int = 25
var salary float64 = 5000.0
var isEmployed bool = true
// 简短变量声明
name2 := “Another Developer”
age2 := 30
// 输出信息
fmt.Printf(“Hello, %s!\n”, name)
fmt.Printf(“Age: %d\n”, age)
fmt.Printf(“Salary: %f\n”, salary)
fmt.Printf(“Employed: %t\n”, isEmployed)
fmt.Printf(“Name2: %s, Age2: %d\n”, name2, age2)
// 控制语句
if age >= 18 {
fmt.Println(“Adult”)
} else {
fmt.Println(“Minor”)
}
// 循环语句
fmt.Println(“Counting from 1 to 5:”)
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
// 函数调用
result := add(10, 20)
fmt.Printf("Sum: %d\n", result)
}
// 函数定义
func add(a, b int) int {
return a + b
}
// 输出:
// Hello, Go Developer!
// Age: 25
// Salary: 5000.000000
// Employed: true
// Name2: Another Developer, Age2: 30
// Adult
// Counting from 1 to 5:
// 1
// 2
// 3
// 4
// 5
// Sum: 30
4. 数据类型与操作
Go语言支持多种数据类型,包括基本类型和复合类型。
package main
import “fmt”
func main() {
// 基本类型
var i int = 42
var f float64 = 3.14
var b bool = true
var c byte = ‘A’
var s string = “Hello, Go!”
fmt.Printf(“Int: %d, type: %T\n”, i, i)
fmt.Printf(“Float64: %f, type: %T\n”, f, f)
fmt.Printf(“Bool: %t, type: %T\n”, b, b)
fmt.Printf(“Byte: %c, type: %T\n”, c, c)
fmt.Printf(“String: %s, type: %T\n”, s, s)
// 复合类型 – 数组
var arr [5]int = [5]int{1, 2, 3, 4, 5}
fmt.Printf(“Array: %v, length: %d\n”, arr, len(arr))
fmt.Printf(“Array[0]: %d\n”, arr[0])
// 复合类型 – 切片
slice := []int{1, 2, 3, 4, 5}
fmt.Printf(“Slice: %v, length: %d, capacity: %d\n”, slice, len(slice), cap(slice))
slice = append(slice, 6)
fmt.Printf(“Slice after append: %v, length: %d, capacity: %d\n”, slice, len(slice), cap(slice))
// 复合类型 – 映射
m := map[string]int{
“Alice”: 25,
“Bob”: 30,
“Charlie”: 35,
}
fmt.Printf(“Map: %v\n”, m)
fmt.Printf(“Alice’s age: %d\n”, m[“Alice”])
m[“David”] = 40
fmt.Printf(“Map after add: %v\n”, m)
// 复合类型 – 结构体
type Person struct {
Name string
Age int
City string
}
p := Person{Name: “Alice”, Age: 25, City: “New York”}
fmt.Printf(“Person: %v\n”, p)
fmt.Printf(“Person.Name: %s\n”, p.Name)
}
// 输出:
// Int: 42, type: int
// Float64: 3.140000, type: float64
// Bool: true, type: bool
// Byte: A, type: uint8
// String: Hello, Go!, type: string
// Array: [1 2 3 4 5], length: 5
// Array[0]: 1
// Slice: [1 2 3 4 5], length: 5, capacity: 5
// Slice after append: [1 2 3 4 5 6], length: 6, capacity: 10
// Map: map[Alice:25 Bob:30 Charlie:35]
// Alice’s age: 25
// Map after add: map[Alice:25 Bob:30 Charlie:35 David:40]
// Person: {Alice 25 New York}
// Person.Name: Alice
5. 控制流语句
Go语言的控制流语句包括条件语句、循环语句等。
package main
import “fmt”
func main() {
// if-else语句
score := 85
if score >= 90 {
fmt.Println(“Grade: A”)
} else if score >= 80 {
fmt.Println(“Grade: B”)
} else if score >= 70 {
fmt.Println(“Grade: C”)
} else if score >= 60 {
fmt.Println(“Grade: D”)
} else {
fmt.Println(“Grade: F”)
}
// switch语句
day := 3
var dayName string
switch day {
case 1:
dayName = “Monday”
case 2:
dayName = “Tuesday”
case 3:
dayName = “Wednesday”
case 4:
dayName = “Thursday”
case 5:
dayName = “Friday”
case 6:
dayName = “Saturday”
case 7:
dayName = “Sunday”
default:
dayName = “Invalid day”
}
fmt.Printf(“Day: %s\n”, dayName)
// for循环
fmt.Println(“For loop:”)
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
// for-range循环
fmt.Println("For-range loop:")
fruits := []string{"Apple", "Banana", "Orange", "Mango"}
for index, fruit := range fruits {
fmt.Printf("Index: %d, Fruit: %s\n", index, fruit)
}
// 无限循环
fmt.Println("Infinite loop (stopped after 3 iterations):")
count := 0
for {
if count >= 3 {
break
}
fmt.Printf(“Count: %d\n”, count)
count++
}
// 带条件的for循环
fmt.Println(“For loop with condition:”)
j := 1
for j <= 5 {
fmt.Println(j)
j++
}
}
// 输出:
// Grade: B
// Day: Wednesday
// For loop:
// 1
// 2
// 3
// 4
// 5
// For-range loop:
// Index: 0, Fruit: Apple
// Index: 1, Fruit: Banana
// Index: 2, Fruit: Orange
// Index: 3, Fruit: Mango
// Infinite loop (stopped after 3 iterations):
// Count: 0
// Count: 1
// Count: 2
// For loop with condition:
// 1
// 2
// 3
// 4
// 5
6. 函数
Go语言的函数是可重用的代码块,支持多返回值、变参等特性。学习交流加群风哥QQ113257174
package main
import “fmt”
// 基本函数
func greet(name string) string {
return fmt.Sprintf(“Hello, %s!”, name)
}
// 多返回值函数
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf(“division by zero”)
}
return a / b, nil
}
// 变参函数
func sum(numbers …int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
// 命名返回值
func calculate(a, b int) (sum, product int) {
sum = a + b
product = a * b
return // 裸返回
}
// 函数作为参数
func applyOperation(a, b int, op func(int, int) int) int {
return op(a, b)
}
// 函数作为返回值
func createMultiplier(factor int) func(int) int {
return func(x int) int {
return x * factor
}
}
func main() {
// 调用基本函数
fmt.Println(greet(“Alice”))
// 调用多返回值函数
result, err := divide(10, 2)
if err != nil {
fmt.Printf(“Error: %v\n”, err)
} else {
fmt.Printf(“10 / 2 = %f\n”, result)
}
// 调用变参函数
fmt.Printf(“Sum of 1, 2, 3, 4, 5: %d\n”, sum(1, 2, 3, 4, 5))
// 调用命名返回值函数
sumResult, productResult := calculate(5, 3)
fmt.Printf(“5 + 3 = %d, 5 * 3 = %d\n”, sumResult, productResult)
// 调用带函数参数的函数
add := func(a, b int) int { return a + b }
multiply := func(a, b int) int { return a * b }
fmt.Printf(“Apply add: %d\n”, applyOperation(5, 3, add))
fmt.Printf(“Apply multiply: %d\n”, applyOperation(5, 3, multiply))
// 调用返回函数的函数
double := createMultiplier(2)
triple := createMultiplier(3)
fmt.Printf(“Double of 5: %d\n”, double(5))
fmt.Printf(“Triple of 5: %d\n”, triple(5))
}
// 输出:
// Hello, Alice!
// 10 / 2 = 5.000000
// Sum of 1, 2, 3, 4, 5: 15
// 5 + 3 = 8, 5 * 3 = 15
// Apply add: 8
// Apply multiply: 15
// Double of 5: 10
// Triple of 5: 15
7. 结构体与方法
Go语言的结构体是一种复合数据类型,可以为结构体定义方法。
package main
import “fmt”
// 定义结构体
type Person struct {
Name string
Age int
}
// 为结构体定义方法
func (p Person) Greet() string {
return fmt.Sprintf(“Hello, my name is %s and I am %d years old”, p.Name, p.Age)
}
// 指针接收器方法(可修改结构体字段)
func (p *Person) Birthday() {
p.Age++
}
// 定义嵌套结构体
type Address struct {
Street string
City string
Country string
}
type Employee struct {
Person
EmployeeID string
Address
}
func main() {
// 创建结构体实例
p := Person{Name: “Alice”, Age: 25}
fmt.Println(p.Greet())
// 调用指针接收器方法
p.Birthday()
fmt.Println(p.Greet())
// 创建嵌套结构体实例
e := Employee{
Person: Person{Name: “Bob”, Age: 30},
EmployeeID: “E123”,
Address: Address{
Street: “123 Main St”,
City: “New York”,
Country: “USA”,
},
}
fmt.Printf(“Employee: %v\n”, e)
fmt.Printf(“Employee Name: %s\n”, e.Name) // 访问嵌入的Person字段
fmt.Printf(“Employee City: %s\n”, e.City) // 访问嵌入的Address字段
fmt.Println(e.Greet()) // 调用嵌入的Person方法
}
// 输出:
// Hello, my name is Alice and I am 25 years old
// Hello, my name is Alice and I am 26 years old
// Employee: {{Bob 30} E123 {123 Main St New York USA}}
// Employee Name: Bob
// Employee City: New York
// Hello, my name is Bob and I am 30 years old
8. 接口
Go语言的接口是一种类型,定义了一组方法签名,任何类型只要实现了这些方法,就实现了该接口。
package main
import “fmt”
// 定义接口
type Animal interface {
Speak() string
Move() string
}
// 实现接口的类型
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return “Woof!”
}
func (d Dog) Move() string {
return “Run”
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return “Meow!”
}
func (c Cat) Move() string {
return “Walk”
}
// 接受接口类型参数的函数
func AnimalInfo(a Animal) {
fmt.Printf(“Animal speaks: %s, moves: %s\n”, a.Speak(), a.Move())
}
func main() {
// 创建实现接口的实例
dog := Dog{Name: “Buddy”}
cat := Cat{Name: “Whiskers”}
// 调用函数,传递不同类型的实例
fmt.Printf(“Dog: %s\n”, dog.Name)
AnimalInfo(dog)
fmt.Printf(“Cat: %s\n”, cat.Name)
AnimalInfo(cat)
// 接口类型变量
var animal Animal
animal = dog
fmt.Printf(“Animal variable (dog): %s\n”, animal.Speak())
animal = cat
fmt.Printf(“Animal variable (cat): %s\n”, animal.Speak())
}
// 输出:
// Dog: Buddy
// Animal speaks: Woof!, moves: Run
// Cat: Whiskers
// Animal speaks: Meow!, moves: Walk
// Animal variable (dog): Woof!
// Animal variable (cat): Meow!
9. 并发编程
Go语言的并发编程是其核心特性之一,通过goroutine和channel实现。更多学习教程公众号风哥教程itpux_com
package main
import “fmt”
import “time”
// 基本goroutine
func sayHello() {
for i := 0; i < 5; i++ {
fmt.Println("Hello from goroutine")
time.Sleep(100 * time.Millisecond)
}
}
// 带参数的goroutine
func sayHelloTo(name string) {
for i := 0; i < 3; i++ {
fmt.Printf("Hello, %s!\n", name)
time.Sleep(150 * time.Millisecond)
}
}
// 使用channel进行通信
func produce(ch chan<- int) {
for i := 1; i <= 5; i++ {
ch <- i // 发送数据到channel
fmt.Printf("Produced: %d\n", i)
time.Sleep(100 * time.Millisecond)
}
close(ch) // 关闭channel
}
func consume(ch <-chan int) {
for value := range ch { // 从channel接收数据,直到channel关闭
fmt.Printf("Consumed: %d\n", value)
time.Sleep(200 * time.Millisecond)
}
}
// 使用sync.WaitGroup等待goroutine完成
import "sync"
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // 减少计数器
fmt.Printf("Worker %d started\n", id)
time.Sleep(time.Duration(id) * 100 * time.Millisecond)
fmt.Printf("Worker %d finished\n", id)
}
func main() {
fmt.Println("=== Basic Goroutine ===")
// 启动goroutine
go sayHello()
// 主goroutine继续执行
for i := 0; i < 3; i++ {
fmt.Println("Hello from main")
time.Sleep(150 * time.Millisecond)
}
fmt.Println("\n=== Goroutine with Parameters ===")
// 启动多个goroutine
go sayHelloTo("Alice")
go sayHelloTo("Bob")
// 等待goroutine完成
time.Sleep(1 * time.Second)
fmt.Println("\n=== Channel Communication ===")
// 创建channel
ch := make(chan int)
// 启动goroutine
go produce(ch)
go consume(ch)
// 等待goroutine完成
time.Sleep(2 * time.Second)
fmt.Println("\n=== WaitGroup ===")
// 创建WaitGroup
var wg sync.WaitGroup
// 启动多个worker
for i := 1; i <= 3; i++ {
wg.Add(1) // 增加计数器
go worker(i, &wg)
}
// 等待所有worker完成
wg.Wait()
fmt.Println("All workers finished")
}
// 输出(顺序可能不同):
// === Basic Goroutine ===
// Hello from main
// Hello from goroutine
// Hello from main
// Hello from goroutine
// Hello from main
// Hello from goroutine
// Hello from goroutine
// Hello from goroutine
//
// === Goroutine with Parameters ===
// Hello, Alice!
// Hello, Bob!
// Hello, Alice!
// Hello, Bob!
// Hello, Alice!
// Hello, Bob!
//
// === Channel Communication ===
// Produced: 1
// Consumed: 1
// Produced: 2
// Produced: 3
// Consumed: 2
// Produced: 4
// Produced: 5
// Consumed: 3
// Consumed: 4
// Consumed: 5
//
// === WaitGroup ===
// Worker 1 started
// Worker 2 started
// Worker 3 started
// Worker 1 finished
// Worker 2 finished
// Worker 3 finished
// All workers finished
10. Go开发最佳实践
Go语言开发最佳实践包括代码规范、性能优化、安全性等多个方面。
# 1. 代码规范
– 遵循Go代码风格指南(gofmt自动格式化)
– 使用有意义的变量和函数命名
– 保持函数简洁,每个函数只做一件事
– 使用短变量声明(:=)但在包级别使用var
– 避免使用全局变量
# 2. 性能优化
– 使用切片代替数组
– 合理使用map
– 避免在循环中创建对象
– 使用sync.Pool复用对象
– 合理使用并发
# 3. 错误处理
– 明确处理错误,不要忽略错误
– 使用errors.New或fmt.Errorf创建错误
– 考虑使用自定义错误类型
– 错误信息应清晰明确
# 4. 并发编程
– 使用goroutine实现并发
– 使用channel进行通信
– 避免共享内存,使用消息传递
– 合理使用sync包中的同步原语
– 注意goroutine泄漏
# 5. 包管理
– 使用Go modules管理依赖
– 明确版本号
– 避免依赖冲突
– 定期更新依赖
# 6. 测试
– 编写单元测试
– 使用testing包
– 考虑使用表驱动测试
– 测试覆盖率应达到合理水平
# 7. 文档
– 使用godoc注释格式
– 为包、函数、类型添加注释
– 提供示例代码
– 保持文档与代码同步
# 8. 工具使用
– 使用gofmt格式化代码
– 使用go vet检查代码
– 使用golint检查代码风格
– 使用pprof分析性能
# 9. 安全性
– 避免使用unsafe包
– 注意输入验证
– 避免SQL注入
– 使用HTTPS
– 定期更新依赖以修复安全漏洞
# 10. 架构设计
– 遵循依赖注入原则
– 使用接口解耦
– 合理分层
– 考虑使用领域驱动设计
– 保持模块间低耦合高内聚
# 代码示例
// 好的实践示例
// 错误处理
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf(“division by zero”)
}
return a / b, nil
}
// 使用
result, err := divide(10, 2)
if err != nil {
log.Printf(“Error: %v”, err)
return
}
fmt.Printf(“Result: %f\n”, result)
// 并发安全
var (
mu sync.Mutex
counter int
)
func increment() {
mu.Lock()
defer mu.Unlock()
counter++
}
// 错误包装
func processFile(filename string) error {
data, err := readFile(filename)
if err != nil {
return fmt.Errorf(“read file %s: %w”, filename, err)
}
// 处理数据
return nil
}
author:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
