好的,让我们来快速入门Go语言的基本语法。Go语言(也称为Golang)是一种静态类型、编译型语言,由Google开发。它以简洁、高效和并发支持著称。
1. 基本结构
一个简单的Go程序的基本结构如下:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
- package main:每个Go程序都从
package main开始。main包是程序的入口点。 - import "fmt":导入标准库中的
fmt包,用于格式化输入输出。 - func main():
main函数是程序的入口点,程序从这里开始执行。
2. 变量和常量
变量
var x int = 10
y := 20 // 简短声明,自动推断类型
var关键字用于声明变量。:=用于简短声明,自动推断类型。
常量
const Pi = 3.14
const关键字用于声明常量。
3. 数据类型
Go语言支持多种基本数据类型:
- 整数类型:
int,int8,int16,int32,int64,uint,uint8,uint16,uint32,uint64 - 浮点类型:
float32,float64 - 复数类型:
complex64,complex128 - 布尔类型:
bool - 字符串类型:
string
4. 控制结构
条件语句
if x > 10 {
fmt.Println("x is greater than 10")
} else if x == 10 {
fmt.Println("x is equal to 10")
} else {
fmt.Println("x is less than 10")
}
循环语句
for i := 0; i < 10; i++ {
fmt.Println(i)
}
// 类似于while循环
i := 0
for i < 10 {
fmt.Println(i)
i++
}
5. 函数
func add(a int, b int) int {
return a + b
}
func main() {
result := add(3, 5)
fmt.Println(result)
}
func关键字用于定义函数。- 函数可以有多个参数和返回值。
6. 数组和切片
数组
var arr [5]int
arr[0] = 1
fmt.Println(arr)
切片
slice := []int{1, 2, 3, 4, 5}
slice = append(slice, 6)
fmt.Println(slice)
- 切片是动态数组,可以动态调整大小。
7. 映射(Map)
m := make(map[string]int)
m["apple"] = 1
m["banana"] = 2
fmt.Println(m)
map是一种键值对的数据结构。
8. 结构体
type Person struct {
Name string
Age int
}
func main() {
p := Person{Name: "Alice", Age: 30}
fmt.Println(p)
}
struct用于定义复杂的数据类型。
9. 并发
Go语言以并发支持著称,使用goroutine和channel来实现并发。
Goroutine
func sayHello() {
fmt.Println("Hello, World!")
}
func main() {
go sayHello() // 启动一个goroutine
time.Sleep(1 * time.Second) // 等待goroutine执行
}
Channel
func main() {
ch := make(chan int)
go func() {
ch <- 42 // 发送数据到channel
}()
value := <-ch // 从channel接收数据
fmt.Println(value)
}
channel用于在不同的goroutine之间传递数据。 并发(Concurrency)是计算机科学中的一个重要概念,指的是在同一时间段内处理多个任务的能力。在现代编程中,并发通常用于提高程序的性能和响应能力。
并发与并行
- 并发:指的是在同一时间段内处理多个任务,但不一定同时执行。例如,操作系统可以在一个CPU核心上交替执行多个任务。
- 并行:指的是同时执行多个任务。例如,多核CPU可以同时执行多个任务。
Go语言中的并发
Go语言(Golang)以其强大的并发支持而闻名。Go语言通过goroutine和channel来实现并发。
1. Goroutine
goroutine是Go语言中的轻量级线程,由Go运行时(runtime)管理。goroutine比传统的线程更轻量,可以创建成千上万个而不会显著增加系统开销。
go
package main
import (
"fmt"
"time"
)
func sayHello() {
fmt.Println("Hello, World!")
}
func main() {
go sayHello() // 启动一个
goroutine
time.Sleep(1 * time.
Second) // 等待goroutine执行
}
go sayHello():启动一个新的goroutine来执行sayHello函数。time.Sleep(1 * time.Second):等待goroutine执行完毕。
2. Channel
channel是Go语言中用于在不同的goroutine之间传递数据的机制。channel可以看作是一个管道,数据可以在其中流动。
go
package main
import "fmt"
func main() {
ch := make(chan int) // 创建一
个int类型的channel
go func() {
ch <- 42 // 发送数据到
channel
}()
value := <-ch // 从channel接收
数据
fmt.Println(value)
}
ch := make(chan int):创建一个int类型的channel。ch <- 42:将数据42发送到channel。value := <-ch:从channel接收数据并赋值给value。
3. Select
select语句用于在多个channel操作中进行选择。它类似于switch语句,但用于channel。
go
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(1 * time.
Second)
ch1 <- "one"
}()
go func() {
time.Sleep(2 * time.
Second)
ch2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-ch1:
fmt.Println
("received", msg1)
case msg2 := <-ch2:
fmt.Println
("received", msg2)
}
}
}
select语句会阻塞,直到其中一个case可以执行。- 如果有多个
case可以执行,select会随机选择一个执行。
4. Mutex
在并发编程中,多个goroutine可能会同时访问共享资源,导致数据竞争(race condition)。sync.Mutex用于解决这个问题。
go
package main
import (
"fmt"
"sync"
)
var (
counter int
mutex sync.Mutex
)
func increment() {
mutex.Lock()
counter++
mutex.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
increment()
}()
}
wg.Wait()
fmt.Println("Counter:",
counter)
}
mutex.Lock():获取锁,确保同一时间只有一个goroutine可以访问共享资源。mutex.Unlock():释放锁,允许其他goroutine访问共享资源。