Go语言(也称为Golang)是由Google开发的一种静态类型、编译型的编程语言,以其简洁性、高效的并发支持而著称。以下是Go语言的一些基础语法要点:
在Go中,变量可以通过var
关键字声明,并且需要指定类型。也可以使用:=
操作符进行简短声明。
var
声明:govar a int
a = 42
gob := "hello"
Go支持多种基本数据类型,包括但不限于:
int
, int8
, int16
, int32
, int64
, uint
, uint8
, uint16
, uint32
, uint64
float32
, float64
bool
string
complex64
, complex128
goif x > 0 {
// 当x大于0时执行的代码
} else if x < 0 {
// 当x小于0时执行的代码
} else {
// 当x等于0时执行的代码
}
for
循环是Go中唯一的循环语句。go// 标准for循环
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// 无限循环
for {
// 需要手动break退出循环
}
函数通过func
关键字定义,可以有参数和返回值。
gofunc add(a int, b int) int {
return a + b
}
func main() {
result := add(5, 7)
fmt.Println(result) // 输出: 12
}
govar arr [5]int
arr[0] = 1
gos := []int{1, 2, 3}
s = append(s, 4)
fmt.Println(s) // 输出: [1 2 3 4]
映射是一种无序键值对集合。
gom := make(map[string]int)
m["apple"] = 2
fmt.Println(m["apple"]) // 输出: 2
用于定义复杂的数据类型。
gotype Person struct {
Name string
Age int
}
func main() {
p := Person{Name: "John", Age: 30}
fmt.Println(p.Name) // 输出: John
}
接口定义了一组方法签名,任何实现了这些方法的类型都被认为实现了该接口。
gotype Speaker interface {
Speak() string
}
type Dog struct{}
func (d Dog) Speak() string {
return "Woof!"
}
func main() {
var s Speaker = Dog{}
fmt.Println(s.Speak()) // 输出: Woof!
}
Go通过goroutine和channel支持简单的并发模型。
gogo func(x int) {
fmt.Println("Goroutine:", x)
}(1)
goch := make(chan int)
go func() {
ch <- 1
}()
fmt.Println(<-ch) // 输出: 1
Go提倡显式错误处理而不是异常机制。
goresult, err := someFunction()
if err != nil {
log.Fatal(err)
}
fmt.Println(result)
Go 使用模块(go.mod
)进行依赖管理和版本控制。从 Go 1.11 开始,默认支持模块功能。
bashgo mod init example.com/myapp
这会在当前目录下创建一个 go.mod
文件,定义了模块路径和依赖项。
go get
命令来添加依赖。bashgo get github.com/some/package
bashgo mod tidy
这个命令会清理未使用的依赖,并确保所有直接和间接依赖都是最新版本。
Go 支持指针,允许你直接操作内存地址,但不支持指针运算(如 C/C++ 中的指针加减)。
goa := 42
p := &a // p 是指向 a 的指针
gofmt.Println(*p) // 输出: 42
方法是一种带有接收者的函数,接收者可以是值类型或指针类型。
gotype MyInt int
func (m *MyInt) Add(n int) {
*m += MyInt(n)
}
func main() {
var m MyInt = 5
m.Add(3)
fmt.Println(m) // 输出: 8
}
接口在 Go 中用于实现多态性。如果一个类型实现了接口的所有方法,则该类型被认为实现了此接口。
gotype Speaker interface {
Speak() string
}
type Mover interface {
Move() string
}
type Dog struct{}
func (d Dog) Speak() string { return "Woof!" }
func (d Dog) Move() string { return "Running" }
func main() {
var s Speaker = Dog{}
var m Mover = Dog{}
fmt.Println(s.Speak()) // 输出: Woof!
fmt.Println(m.Move()) // 输出: Running
}
Go 支持通过匿名字段实现组合(Composition),这种方式常被称为“嵌入”。
gotype Animal struct {
Name string
}
func (a *Animal) Eat() {
fmt.Println(a.Name, "is eating")
}
type Dog struct {
Animal // 嵌入 Animal
}
func main() {
d := Dog{Animal{Name: "Buddy"}}
d.Eat() // 输出: Buddy is eating
}
defer
关键字用于安排一个函数调用在周围的函数返回之后执行。通常用于资源清理。
gofunc main() {
defer fmt.Println("World")
fmt.Println("Hello")
}
// 输出:
// Hello
// World
闭包是一个函数值,它引用了其函数体内定义的变量。这些变量会被保存在闭包中,即使它们超出了原始作用域。
gofunc makeAdder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
adder := makeAdder()
fmt.Println(adder(1)) // 输出: 1
fmt.Println(adder(2)) // 输出: 3
}
select
语句用于等待多个通信操作。它类似于 switch
,但专门用于通道操作。
goch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(time.Second * 1)
ch1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
ch2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-ch1:
fmt.Println("Received", msg1)
case msg2 := <-ch2:
fmt.Println("Received", msg2)
}
}
// 可能输出:
// Received one
// Received two
Go 提供了内置的测试框架。测试文件名应以 _test.go
结尾。
gopackage mypkg
import "testing"
func TestAdd(t *testing.T) {
result := add(2, 3)
if result != 5 {
t.Errorf("Expected 5, got %d", result)
}
}
bashgo test ./...
以上是对 Go 语言更全面的基础语法介绍。