在本章中,我们将深入探讨 Go 语言的结构。Go 语言以其简洁、高效和强大的并发模型而闻名,了解其基本结构对于编写高效的 Go 代码至关重要。
变量声明与赋值
变量声明
在 Go 语言中,变量声明使用 var 关键字。变量声明可以指定类型,也可以由编译器自动推断类型。例如:
var a int // 显式声明变量类型 var b = 42 // 自动推断变量类型
此外,Go 还提供了简短声明方式,使用 := 来声明并初始化变量:
c := 50 // 简短声明并初始化变量
变量作用域
Go 语言中的变量作用域分为包级别和函数级别。包级别的变量可以在整个包中访问,而函数级别的变量只能在其定义的函数内部访问。
// www.javascriptcn.com code example
package main
import "fmt"
var globalVar = 100 // 包级别的变量
func main() {
localVar := 200 // 函数级别的变量
fmt.Println(globalVar)
fmt.Println(localVar)
}常量声明
常量在 Go 中使用 const 关键字声明。常量一旦被赋值就不能再修改。
const Pi = 3.141592653589793238
// 多个常量的声明
const (
A = 1
B = 2
)数据类型
Go 语言支持多种数据类型,包括但不限于整型、浮点型、布尔型以及字符串等。
整型
Go 语言支持有符号和无符号整型。常见的整型包括 int, int8, int16, int32, int64 和 uint, uint8, uint16, uint32, uint64。
var i int = 100 var u uint = 200
浮点型
Go 语言中的浮点型包括 float32 和 float64。
var f float32 = 3.14 var d float64 = 2.71828
布尔型
布尔型只有两种取值:true 和 false。
var isTrue bool = true
字符串
Go 语言中的字符串是不可变的,使用双引号或反引号表示。
s1 := "Hello, World!" s2 := `This is a multi-line string.`
控制结构
Go 语言支持常见的控制结构,如条件语句和循环语句。
条件语句
Go 使用 if 和 switch 语句进行条件判断。
// www.javascriptcn.com code example
age := 20
if age >= 18 {
fmt.Println("成年人")
} else {
fmt.Println("未成年人")
}
switch day := time.Now().Weekday(); day {
case time.Saturday, time.Sunday:
fmt.Println("周末")
default:
fmt.Println("工作日")
}循环语句
Go 语言支持 for 循环,也允许使用 goto 语句跳转到标签。
// www.javascriptcn.com code example
sum := 1
for i := 1; i <= 100; i++ {
sum += i
}
label:
fmt.Println(sum)
// 使用 goto 跳转
goto label函数
函数是 Go 语言的基本构建块。函数可以返回一个或多个值,并且可以接受可变数量的参数。
定义与调用
func add(a int, b int) int {
return a + b
}
result := add(5, 3)
fmt.Println(result)多返回值
Go 允许函数返回多个值,这在处理错误时特别有用。
// www.javascriptcn.com code example
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("除数不能为零")
}
return a / b, nil
}
quotient, err := divide(10, 0)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(quotient)
}可变参数
函数可以接受可变数量的参数,通过在参数类型后添加 ... 实现。
// www.javascriptcn.com code example
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
fmt.Println(sum(1, 2, 3, 4))数组与切片
数组和切片是 Go 语言中用于存储一组相同类型数据的数据结构。
数组
数组是一个固定长度的元素序列,所有元素必须是相同的类型。
var arr [5]int arr[0] = 1 arr[1] = 2 slice := arr[:3] // 创建一个切片,指向数组的前三个元素
切片
切片是对数组的一个连续片段的引用,它是一个动态的、灵活的数据结构。
nums := []int{1, 2, 3, 4, 5}
fmt.Println(nums)
// 切片操作
slice := nums[1:3]
fmt.Println(slice)映射
映射是一种关联键和值的数据结构。映射中的键是唯一的,但值可以重复。
// www.javascriptcn.com code example
ages := make(map[string]int)
ages["Alice"] = 30
ages["Bob"] = 25
age, exists := ages["Charlie"]
if !exists {
fmt.Println("Charlie 不在映射中")
} else {
fmt.Println(age)
}
delete(ages, "Alice") // 删除键值对结构体
结构体是一种用户自定义的数据类型,它可以包含字段和方法。
定义与实例化
type Person struct {
Name string
Age int
}
p := Person{Name: "John", Age: 30}方法
在 Go 语言中,可以为结构体定义方法。
func (p Person) SayHello() {
fmt.Printf("Hello, my name is %s\n", p.Name)
}
p.SayHello()接口
接口定义了一组方法签名,任何实现了这些方法的类型都可以被视为该接口的实现。
// www.javascriptcn.com code example
type Speaker interface {
SayHello()
}
type Employee struct {
Name string
}
func (e Employee) SayHello() {
fmt.Printf("Hello, I'm an employee named %s\n", e.Name)
}
var speaker Speaker = Employee{Name: "Jane"}
speaker.SayHello()并发编程
Go 语言内置了对并发的支持,主要通过 goroutines 和 channels 实现。
Goroutines
Goroutines 是轻量级线程,Go 语言通过启动一个新的 goroutine 来执行并发任务。
// www.javascriptcn.com code example
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(time.Millisecond * 100)
fmt.Println(s)
}
}
go say("world")
say("hello")Channels
Channels 是在 goroutines 之间传递数据的安全通道。
ch := make(chan int, 2) ch <- 1 ch <- 2 fmt.Println(<-ch) fmt.Println(<-ch)
通过本章的学习,你应该已经掌握了 Go 语言的基础结构。这些基础知识将帮助你在后续的学习中更好地理解和应用 Go 语言。