Go语言入门指南:从零开始学Go

张开发
2026/4/18 11:37:20 15 分钟阅读

分享文章

Go语言入门指南:从零开始学Go
Go语言入门指南从零开始学Go为什么选择Go语言Go语言又称Golang是由Google开发的一门静态类型、编译型编程语言。自2009年发布以来Go语言凭借其简洁的语法、出色的性能和强大的并发支持迅速成为后端开发的热门选择。选择Go语言的理由简洁易学Go语言的语法简洁明了学习曲线平缓高性能编译型语言执行效率高接近C/C的性能强大的并发支持原生支持goroutine和channel轻松实现高并发丰富的标准库标准库功能强大涵盖网络、IO、加密等常用功能快速编译编译速度极快提高开发效率跨平台支持Windows、Linux、macOS等多种操作系统垃圾回收自动内存管理减少内存泄漏风险环境搭建安装GoWindows下载安装包双击安装即可macOS使用Homebrew安装brew install goLinux下载tar包解压配置环境变量安装完成后验证安装go version配置GOPATHGo 1.13版本后推荐使用Go Modules管理依赖不再需要配置GOPATH。但了解GOPATH有助于理解Go的历史# 查看Go环境变量 go env # 设置GOPATH可选 export GOPATH$HOME/go export PATH$PATH:$GOPATH/bin选择IDE推荐的Go开发工具VS Code轻量级插件丰富免费GoLandJetBrains出品功能强大付费Vim/Neovim配合插件适合命令行爱好者第一个Go程序创建文件hello.gopackage main import fmt func main() { fmt.Println(Hello, World!) }运行程序# 直接运行 go run hello.go # 编译后运行 go build hello.go ./helloGo语言基础语法包声明每个Go文件都必须以包声明开头package main // 可执行程序的入口包导入包使用import关键字导入包import fmt import math // 或者使用分组导入 import ( fmt math strings )变量声明Go语言有多种变量声明方式// 完整声明 var name string John var age int 30 // 类型推断 var name John // 编译器自动推断为string var age 30 // 编译器自动推断为int // 短变量声明只能在函数内部使用 name : John age : 30 // 多个变量声明 var a, b, c int 1, 2, 3 var x, y 1, hello // 批量声明 var ( name string John age int 30 isActive bool true )常量声明使用const关键字声明常量const Pi 3.14159 const ( Monday iota // 0 Tuesday // 1 Wednesday // 2 Thursday // 3 Friday // 4 Saturday // 5 Sunday // 6 )数据类型Go语言的基本数据类型// 布尔类型 var flag bool true // 整型 var i int 10 // 平台相关32或64位 var i8 int8 127 // -128 ~ 127 var i16 int16 32767 // -32768 ~ 32767 var i32 int32 2147483647 var i64 int64 9223372036854775807 var ui uint 10 // 无符号整型 var ui8 uint8 255 // 0 ~ 255 var ui16 uint16 65535 var ui32 uint32 4294967295 var ui64 uint64 18446744073709551615 // 浮点型 var f32 float32 3.14 var f64 float64 3.141592653589793 // 复数 var c64 complex64 1 2i var c128 complex128 1 2i // 字符串 var str string Hello, Go! // 字节和符文 var b byte a // uint8的别名 var r rune 中 // int32的别名用于Unicode字符运算符Go语言支持常见的运算符// 算术运算符 a b // 加法 a - b // 减法 a * b // 乘法 a / b // 除法 a % b // 取模 // 比较运算符 a b // 等于 a ! b // 不等于 a b // 大于 a b // 小于 a b // 大于等于 a b // 小于等于 // 逻辑运算符 a b // 逻辑与 a || b // 逻辑或 !a // 逻辑非 // 位运算符 a b // 按位与 a | b // 按位或 a ^ b // 按位异或 a ^ b // 按位清除 a b // 左移 a b // 右移控制流程条件语句// if语句 if x 0 { fmt.Println(x是正数) } else if x 0 { fmt.Println(x是负数) } else { fmt.Println(x是零) } // if语句中可以包含初始化语句 if err : doSomething(); err ! nil { fmt.Println(出错了:, err) }循环语句Go语言只有一种循环语句for但功能强大// 基本for循环 for i : 0; i 10; i { fmt.Println(i) } // 条件循环类似while i : 0 for i 10 { fmt.Println(i) i } // 无限循环 for { fmt.Println(无限循环) break // 使用break退出 } // 遍历数组/切片 numbers : []int{1, 2, 3, 4, 5} for index, value : range numbers { fmt.Printf(索引: %d, 值: %d\n, index, value) } // 遍历map scores : map[string]int{Alice: 90, Bob: 85} for name, score : range scores { fmt.Printf(%s: %d\n, name, score) }switch语句// 基本switch switch day { case Monday: fmt.Println(星期一) case Tuesday: fmt.Println(星期二) case Wednesday, Thursday, Friday: fmt.Println(工作日) default: fmt.Println(周末) } // 带表达式的switch score : 85 switch { case score 90: fmt.Println(优秀) case score 80: fmt.Println(良好) case score 60: fmt.Println(及格) default: fmt.Println(不及格) } // switch中的fallthrough n : 1 switch n { case 1: fmt.Println(1) fallthrough // 继续执行下一个case case 2: fmt.Println(2) case 3: fmt.Println(3) }函数函数定义// 基本函数 func add(a int, b int) int { return a b } // 多个参数类型相同可以简写 func add(a, b int) int { return a b } // 多返回值 func divide(a, b float64) (float64, error) { if b 0 { return 0, errors.New(除数不能为零) } return a / b, nil } // 命名返回值 func rectangle(width, height float64) (area, perimeter float64) { area width * height perimeter 2 * (width height) return // naked return自动返回命名返回值 } // 可变参数 func sum(nums ...int) int { total : 0 for _, num : range nums { total num } return total } // 使用 result : sum(1, 2, 3, 4, 5) // 15函数作为参数和返回值// 函数作为参数 func applyOperation(a, b int, op func(int, int) int) int { return op(a, b) } // 函数作为返回值 func makeMultiplier(factor int) func(int) int { return func(x int) int { return x * factor } } // 使用 add : func(a, b int) int { return a b } result : applyOperation(3, 4, add) // 7 double : makeMultiplier(2) fmt.Println(double(5)) // 10数组和切片数组数组是固定长度的序列// 声明数组 var arr [5]int // [0 0 0 0 0] arr2 : [5]int{1, 2, 3, 4, 5} // [1 2 3 4 5] arr3 : [...]int{1, 2, 3} // 长度自动推断为3 arr4 : [5]int{1: 10, 3: 30} // [0 10 0 30 0] // 数组长度是类型的一部分 var a [3]int var b [5]int // a b // 编译错误类型不同 // 多维数组 var matrix [3][3]int matrix[0][0] 1切片切片是动态数组更常用// 创建切片 slice1 : []int{1, 2, 3, 4, 5} slice2 : make([]int, 5) // 长度5容量5 slice3 : make([]int, 3, 10) // 长度3容量10 // 从数组创建切片 arr : [5]int{1, 2, 3, 4, 5} slice : arr[1:4] // [2 3 4] // 切片操作 slice append(slice, 6) // 追加元素 slice append(slice, 7, 8, 9) // 追加多个元素 // 复制切片 src : []int{1, 2, 3} dst : make([]int, len(src)) copy(dst, src) // 切片的切片 sliceOfSlice : [][]int{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, }MapMap是键值对的数据结构// 创建map m1 : make(map[string]int) m2 : map[string]int{ Alice: 90, Bob: 85, } // 操作map m1[Charlie] 95 // 添加/修改 score : m1[Alice] // 访问 score, ok : m1[David] // 安全访问ok为false表示key不存在 // 删除 delete(m1, Alice) // 遍历 for key, value : range m2 { fmt.Printf(%s: %d\n, key, value) }结构体结构体用于定义自定义类型// 定义结构体 type Person struct { Name string Age int Email string Address Address } type Address struct { City string Street string ZipCode string } // 创建结构体实例 p1 : Person{ Name: Alice, Age: 30, Email: aliceexample.com, } p2 : Person{Name: Bob, Age: 25} // 部分初始化 p3 : Person{Charlie, 35, charlieexample.com, Address{}} // 按位置初始化 // 访问字段 fmt.Println(p1.Name) p1.Age 31 // 指针访问 p : p1 fmt.Println(p.Name) // 自动解引用等价于 (*p).Name方法方法是绑定到类型的函数type Rectangle struct { Width float64 Height float64 } // 值接收者方法 func (r Rectangle) Area() float64 { return r.Width * r.Height } // 指针接收者方法可以修改原对象 func (r *Rectangle) Scale(factor float64) { r.Width * factor r.Height * factor } // 使用 rect : Rectangle{Width: 10, Height: 5} fmt.Println(rect.Area()) // 50 rect.Scale(2) fmt.Println(rect.Area()) // 200接口接口定义了一组方法签名// 定义接口 type Shape interface { Area() float64 Perimeter() float64 } // 实现接口 type Circle struct { Radius float64 } func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius } func (c Circle) Perimeter() float64 { return 2 * math.Pi * c.Radius } // 使用接口 func printShapeInfo(s Shape) { fmt.Printf(Area: %.2f\n, s.Area()) fmt.Printf(Perimeter: %.2f\n, s.Perimeter()) } // 空接口可以接收任何类型 var any interface{} any 42 any hello any true错误处理Go语言使用显式错误处理// 创建错误 err : errors.New(something went wrong) // 格式化错误 err : fmt.Errorf(failed to process %s: %w, filename, originalErr) // 错误处理 result, err : someFunction() if err ! nil { log.Printf(Error: %v, err) return } // 自定义错误类型 type ValidationError struct { Field string Message string } func (e ValidationError) Error() string { return fmt.Sprintf(validation error in field %s: %s, e.Field, e.Message) }并发编程基础GoroutineGoroutine是轻量级线程func sayHello() { fmt.Println(Hello) } // 启动goroutine go sayHello() // 匿名函数goroutine go func() { fmt.Println(World) }() // 带参数的goroutine go func(msg string) { fmt.Println(msg) }(Hello from goroutine) // 等待goroutine完成 time.Sleep(time.Second)ChannelChannel用于goroutine间通信// 创建channel ch : make(chan int) // 无缓冲channel ch : make(chan int, 10) // 有缓冲channel // 发送和接收 ch - 42 // 发送 value : -ch // 接收 // 关闭channel close(ch) // 检查channel是否关闭 value, ok : -ch if !ok { fmt.Println(Channel is closed) } // range遍历channel for value : range ch { fmt.Println(value) } // select多路复用 select { case v1 : -ch1: fmt.Println(Received from ch1:, v1) case v2 : -ch2: fmt.Println(Received from ch2:, v2) case ch3 - 100: fmt.Println(Sent to ch3) default: fmt.Println(No channel ready) }常用标准库fmt - 格式化IOfmt.Println(Hello) // 打印并换行 fmt.Printf(Name: %s, Age: %d\n, name, age) fmt.Sprintf(Name: %s, name) // 返回字符串 fmt.Scanln(name) // 读取输入strings - 字符串处理strings.Contains(hello, ell) // true strings.HasPrefix(hello, he) // true strings.HasSuffix(hello, lo) // true strings.ToUpper(hello) // HELLO strings.ToLower(HELLO) // hello strings.TrimSpace( hello ) // hello strings.Split(a,b,c, ,) // [a, b, c] strings.Join([]string{a, b}, ,) // a,b strings.Replace(hello, l, x, 1) // hexlotime - 时间处理now : time.Now() fmt.Println(now.Format(2006-01-02 15:04:05)) // 时间解析 t, _ : time.Parse(2006-01-02, 2024-01-15) // 时间运算 duration : time.Hour * 24 future : now.Add(duration) diff : future.Sub(now) // 定时器 ticker : time.NewTicker(time.Second) for range ticker.C { fmt.Println(Tick) }os - 操作系统功能// 环境变量 os.Getenv(HOME) os.Setenv(KEY, value) // 文件操作 file, err : os.Open(file.txt) file, err : os.Create(newfile.txt) os.Remove(file.txt) os.Rename(old.txt, new.txt) // 目录操作 os.Mkdir(newdir, 0755) os.MkdirAll(path/to/dir, 0755) os.RemoveAll(dir)net/http - HTTP服务// 简单的HTTP服务器 http.HandleFunc(/, func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, Hello, %s!, r.URL.Path[1:]) }) http.ListenAndServe(:8080, nil) // HTTP客户端 resp, err : http.Get(https://api.example.com/data) if err ! nil { log.Fatal(err) } defer resp.Body.Close() body, _ : ioutil.ReadAll(resp.Body) fmt.Println(string(body))项目结构一个典型的Go项目结构myproject/ ├── cmd/ │ └── myapp/ │ └── main.go # 应用程序入口 ├── internal/ │ ├── config/ │ │ └── config.go # 配置管理 │ ├── database/ │ │ └── database.go # 数据库连接 │ └── service/ │ └── service.go # 业务逻辑 ├── pkg/ │ └── utils/ │ └── utils.go # 工具函数 ├── go.mod # 模块定义 ├── go.sum # 依赖锁定 └── README.md学习资源推荐官方文档Go官方文档Go语言规范Effective Go在线教程Go by ExampleA Tour of Go书籍推荐《Go程序设计语言》The Go Programming Language《Go语言实战》Go in Action《Go语言高级编程》实践项目编写一个简单的Web服务器实现一个命令行工具开发一个RESTful API构建一个并发爬虫总结Go语言以其简洁、高效和强大的并发支持成为现代后端开发的重要选择。本文介绍了Go语言的基础知识包括环境搭建和第一个程序基础语法变量、常量、数据类型、运算符控制流程条件、循环、switch函数和方法数组、切片和Map结构体和接口错误处理并发编程基础常用标准库项目结构掌握这些基础知识后你可以开始构建自己的Go项目。记住编程是一门实践性很强的技能多写代码、多思考、多总结才能真正掌握Go语言的精髓。祝你在Go语言的学习之路上取得成功

更多文章