Go 语言入门教程笔记
下面是一个全面的 Go 语言教程,适合初学者和有一定编程经验的人士。Go(也称为 Golang)是一种由 Google 开发的开源编程语言,以其简洁、高效和并发支持而闻名。
1. 简介
- 定义:Go 是一种静态类型的编译型语言,设计目的是为了提高开发效率和代码可维护性。
- 用途:
- Web 后端开发。
- 网络编程。
- 并发处理。
- 微服务架构。
- 命令行工具。
- 特点:
- 简洁的语法。
- 内置垃圾回收机制。
- 强大的并发支持(Goroutines 和 Channels)。
- 快速的编译速度。
- 跨平台支持。
2. 安装 Go
在 Windows 上安装
- 访问 Go 官方网站 下载 Windows 安装包。
- 运行下载的
.msi
文件并按照提示进行安装。 - 配置环境变量
GOPATH
和GOROOT
。
在 macOS 上安装
- 使用 Homebrew 安装 Go:
brew install go
在 Linux 上安装
- 使用包管理器安装 Go:
sudo apt-get update sudo apt-get install golang
3. 第一个 Go 程序
创建项目目录
- 创建一个新的目录用于存放你的 Go 项目,例如
mygo
。 - 设置
GOPATH
环境变量指向该目录。
编写第一个程序
- 在
mygo/src
目录下创建一个新的文件夹,例如hello
。 - 在
hello
文件夹中创建一个名为main.go
的文件。 - 编辑
main.go
文件,添加以下内容:package main import "fmt" func main() { fmt.Println("Hello, World!") }
运行程序
- 打开终端,导航到
hello
文件夹。 - 运行以下命令编译并运行程序:
go run main.go
- 你应该会看到输出
Hello, World!
。
4. Go 语言基础语法
注释
- 单行注释使用
//
。 - 多行注释使用
/* ... */
。
// 这是单行注释
/*
这是多行注释
可以跨越多行
*/
变量
- 使用
var
关键字声明变量。 - 支持类型推断。
var a int = 42
b := 3.14
c := true
d := "Hello, World!"
数据类型
- 基本类型:
int
,float64
,bool
,string
。 - 复合类型:
array
,slice
,map
,struct
。
var myInt int = 42
var myFloat float64 = 3.14
var myBool bool = true
var myString string = "Hello, World!"
var myArray [3]int = [3]int{1, 2, 3}
var mySlice []int = []int{1, 2, 3}
var myMap map[string]int = map[string]int{"one": 1, "two": 2}
type Person struct {
Name string
Age int
}
var p Person = Person{Name: "Alice", Age: 30}
字符串
- 使用双引号
"
或反引号`
定义字符串。 - 反引号定义的字符串支持多行和原始字符串。
s1 := "Hello, World!"
s2 := `This is a
multi-line string.`
数组和切片
- 数组是固定长度的。
- 切片是动态数组。
// 数组
var arr [3]int = [3]int{1, 2, 3}
fmt.Println(arr) // 输出: [1 2 3]
// 切片
var slice []int = []int{1, 2, 3}
fmt.Println(slice) // 输出: [1 2 3]
// 添加元素到切片
slice = append(slice, 4)
fmt.Println(slice) // 输出: [1 2 3 4]
控制结构
条件语句
if...else
语句
age := 18
if age >= 18 {
fmt.Println("You are an adult.")
} else {
fmt.Println("You are a minor.")
}
switch
语句
day := "Monday"
switch day {
case "Monday":
fmt.Println("It's Monday")
case "Tuesday", "Wednesday":
fmt.Println("It's midweek")
default:
fmt.Println("It's the weekend")
}
循环
for
循环
for i := 0; i < 5; i++ {
fmt.Println(i) // 输出: 0 1 2 3 4
}
// 无限循环
for {
fmt.Println("Infinite loop")
break
}
// 使用 range 遍历数组或切片
arr := [3]int{1, 2, 3}
for index, value := range arr {
fmt.Printf("Index: %d, Value: %d\n", index, value)
}
5. 函数
定义函数
- 使用
func
关键字定义函数。
package main
import "fmt"
func greet(name string) string {
return "Hello, " + name + "!"
}
func main() {
fmt.Println(greet("Alice")) // 输出: Hello, Alice!
}
默认参数
- Go 不支持默认参数,但可以通过变通方法实现类似功能。
package main
import "fmt"
func greet(name string, greeting string) string {
if greeting == "" {
greeting = "Hello"
}
return greeting + ", " + name + "!"
}
func main() {
fmt.Println(greet("Alice", "")) // 输出: Hello, Alice!
fmt.Println(greet("Bob", "Hi there")) // 输出: Hi there, Bob!
}
可变参数
- 使用
...
表示可变参数。
package main
import "fmt"
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
func main() {
fmt.Println(sum(1, 2, 3, 4)) // 输出: 10
}
6. 结构体和方法
结构体
- 使用
type
关键字定义结构体。
package main
import "fmt"
type Person struct {
Name string
Age int
}
func (p Person) sayHello() string {
return "Hello, my name is " + p.Name
}
func main() {
p := Person{Name: "Alice", Age: 30}
fmt.Println(p.sayHello()) // 输出: Hello, my name is Alice
}
方法
- 结构体的方法通过接收者来定义。
package main
import "fmt"
type Person struct {
Name string
Age int
}
func (p *Person) setName(name string) {
p.Name = name
}
func (p Person) getName() string {
return p.Name
}
func main() {
p := &Person{Name: "Alice", Age: 30}
p.setName("Bob")
fmt.Println(p.getName()) // 输出: Bob
}
7. 接口
定义接口
- 使用
interface
关键字定义接口。
package main
import "fmt"
type Animal interface {
makeSound() string
}
type Dog struct{}
func (d Dog) makeSound() string {
return "Woof!"
}
type Cat struct{}
func (c Cat) makeSound() string {
return "Meow!"
}
func main() {
var a Animal
d := Dog{}
c := Cat{}
a = d
fmt.Println(a.makeSound()) // 输出: Woof!
a = c
fmt.Println(a.makeSound()) // 输出: Meow!
}
8. 并发编程
Goroutines
- 使用
go
关键字启动一个 Goroutine。
package main
import (
"fmt"
"time"
)
func printNumbers() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
time.Sleep(time.Second)
}
}
func main() {
go printNumbers()
fmt.Println("Main function continues to execute.")
time.Sleep(6 * time.Second) // 等待 Goroutine 完成
}
Channels
- 使用
chan
类型定义通道。
package main
import "fmt"
func sendData(ch chan<- int) {
ch <- 42
}
func receiveData(ch <-chan int) {
data := <-ch
fmt.Println("Received:", data)
}
func main() {
ch := make(chan int)
go sendData(ch)
go receiveData(ch)
time.Sleep(2 * time.Second) // 等待 Goroutine 完成
}
9. 错误处理
错误类型
- Go 中的错误通常是一个实现了
error
接口的类型。
package main
import (
"errors"
"fmt"
)
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}
}
10. 包管理
导入包
- 使用
import
关键字导入包。
import (
"fmt"
"math/rand"
)
创建自定义包
- 创建一个新的目录,例如
mymath
。 - 在
mymath
目录下创建一个mymath.go
文件。 - 定义包名和函数。
// mymath/mymath.go
package mymath
func Add(a, b int) int {
return a + b
}
- 在主程序中导入并使用自定义包。
package main
import (
"fmt"
"mymath"
)
func main() {
result := mymath.Add(10, 20)
fmt.Println("Result:", result) // 输出: Result: 30
}
总结
以上是一个全面的 Go 语言入门教程,涵盖了从基础语法到结构体、方法、接口、并发编程和包管理的基本步骤。通过这些基础知识,你可以开始编写简单的 Go 应用程序,并进一步探索更复杂的功能和创意。