Go 基础语法 | 青训营

39 阅读6分钟

Go 语言是一种开源的编程语言,它旨在使程序员更加高效、快速和简洁地编写可靠和易维护的软件。Go 语言具有以下特点:

  • 简洁:Go 语言的语法简单,没有冗余的关键字和符号,代码风格统一,易于阅读和编写。
  • 高效:Go 语言支持原生的并发机制,可以充分利用多核和网络资源,提高程序的性能和吞吐量。
  • 安全:Go 语言有严格的类型检查,避免了一些常见的编程错误,如空指针、数组越界、内存泄漏等。
  • 灵活:Go 语言有独特的接口类型,可以实现多态和泛型等功能,支持模块化和组合式的程序设计。

基础语法

变量

变量是程序中用来存储数据的标识符。在 Go 语言中,变量的声明方式有以下几种:

  • 使用 var 关键字声明一个或多个变量,可以指定变量的类型,也可以省略类型让编译器自动推断。
var x int // 声明一个名为 x 的整型变量
var y, z = 1, 2 // 声明两个变量 y 和 z,并赋值为 1 和 2
var ( // 声明多个变量
    a string
    b bool
    c float64
)
  • 使用短变量声明 := 来声明并初始化一个或多个变量,只能在函数内部使用。
x := 10 // 声明并初始化一个名为 x 的变量,类型为 int
y, z := "hello", "world" // 声明并初始化两个变量 y 和 z,类型为 string
  • 使用 const 关键字声明一个或多个常量,常量是不可修改的变量。
const pi = 3.14 // 声明一个名为 pi 的常量,值为 3.14
const ( // 声明多个常量
    e = 2.718
    g = 9.8
)

数据类型

Go 语言有以下几种基本的数据类型:

  • 数值类型:包括整型(int)、浮点型(float64)、复数型(complex128)等。
  • 字符串类型:表示一系列字符的值,使用双引号或反引号包裹。
  • 布尔类型:表示真或假的值,只有两个预定义常量 truefalse
  • 数组类型:表示固定长度且元素类型相同的序列。
  • 切片类型:表示可变长度且元素类型相同的序列。
  • 映射类型:表示键值对的集合,键和值可以是任意类型。
  • 结构体类型:表示一组具有名字和类型的字段的集合。
  • 函数类型:表示一种可以被调用的代码块,可以接受参数并返回结果。
  • 接口类型:表示一种抽象的规范,定义了一组方法签名,任何实现了这些方法的类型都属于该接口。
  • 指针类型:表示一个存储了另一个变量地址的变量,可以通过 * 操作符来获取或修改指针指向的变量的值,可以通过 & 操作符来获取一个变量的指针。

以下是一些数据类型的示例:

var i int = 42 // 整型
var f float64 = 3.14 // 浮点型
var c complex128 = 1 + 2i // 复数型
var s string = "Hello, world!" // 字符串类型
var b bool = true // 布尔类型
var a [3]int = [3]int{1, 2, 3} // 数组类型,长度为 3,元素类型为 int
var sl []int = []int{4, 5, 6} // 切片类型,长度可变,元素类型为 int
var m map[string]int = map[string]int{"one": 1, "two": 2} // 映射类型,键类型为 string,值类型为 int
type Person struct { // 结构体类型,定义了一个名为 Person 的类型
    Name string // 字段名为 Name,类型为 string
    Age int // 字段名为 Age,类型为 int
}
var p Person = Person{"Alice", 20} // 结构体类型的变量,初始化为 {"Alice", 20}
func add(x, y int) int { // 函数类型,定义了一个名为 add 的函数,接受两个 int 类型的参数,返回一个 int 类型的结果
    return x + y
}
type Adder interface { // 接口类型,定义了一个名为 Adder 的接口,规定了一个方法签名为 add(x, y int) int 的方法
    add(x, y int) int
}
type Calculator struct {} // 结构体类型,定义了一个名为 Calculator 的类型
func (c Calculator) add(x, y int) int { // 为 Calculator 类型定义了一个方法,实现了 Adder 接口的 add 方法
    return x + y
}
var ad Adder = Calculator{} // 接口类型的变量,可以赋值为任何实现了 Adder 接口的类型的值,如 Calculator{}
var pi *int = &i // 指针类型,存储了变量 i 的地址

控制流

控制流是程序中执行语句的顺序和分支。Go 语言有以下几种控制流语句:

  • 条件语句:使用 ifelse 关键字来根据条件执行不同的分支。
if x > 0 {
    fmt.Println("x is positive")
} else if x < 0 {
    fmt.Println("x is negative")
} else {
    fmt.Println("x is zero")
}
  • 循环语句:使用 for 关键字来重复执行一段代码,直到满足某个条件或者使用 break 关键字跳出循环。
// 使用 for 初始化;条件;后续 的形式创建一个循环
for i := 0; i < 10; i++ {
    fmt.Println(i)
}

// 使用 for 条件 的形式创建一个类似 while 的循环
n := 1
for n < 100 {
    n *= 2
}

// 使用 for 的形式创建一个无限循环,直到遇到 break 或 return 跳出循环
sum := 0
for {
    sum++
    if sum > 1000 {
        break
    }
}

// 使用 for range 的形式遍历一个数组、切片、映射或通道中的元素
a := []int{1, 2, 3}
for i, v := range a {
    fmt.Println(i, v)
}
  • 选择语句:使用 switch 关键字来根据表达式的值选择不同的分支执行。
// 使用 switch 表达式 的形式创建一个选择语句,可以省略 break,默认执行完一个分支后就跳出选择语句
switch x {
case 0:
    fmt.Println("x is zero")
case 1:
    fmt.Println("x is one")
default:
    fmt.Println("x is neither zero nor one")
}

// 使用 switch 的形式创建一个选择语句,可以在每个分支中使用条件表达式
switch { 
case x > 0: 
    fmt.Println("x is positive") 
case x < 0:
    fmt.Println("x is negative") 
default: 
    fmt.Println("x is zero")
 } 
// 使用 switch val := expr 的形式创建一个选择语句,可以在每个分支中使用 val 变量,val 的作用域只在 switch 中 
switch val := x * y; { 
case val > 0:
     fmt.Println("val is positive")
 case val < 0: 
    fmt.Println("val is negative") 
default: 
    fmt.Println("val is zero")
 }

函数

函数是一种可以被调用的代码块,可以接受参数并返回结果。Go 语言中,函数是一等公民,可以作为值传递给其他函数,也可以作为返回值返回给调用者。Go 语言支持多个返回值,可以使用 () 括起来表示。Go 语言也支持可变参数,可以使用 ... 表示。

函数的定义格式如下:

func function_name(parameter_list) (return_list) { // 函数体 } Copy

其中:

func 是关键字,表示这是一个函数定义。

function_name 是函数的名称,必须以字母或下划线开头,不能与关键字或预定义标识符重名。

parameter_list 是参数列表,用于接收调用者传递的参数。参数列表由参数名和参数类型组成,多个参数之间用 , 分隔。参数列表可以为空,也可以有多个参数。参数列表可以使用 () 括起来,也可以省略 ()。

return_list 是返回值列表,用于向调用者返回结果。返回值列表由返回值名和返回值类型组成,多个返回值之间用 , 分隔。返回值列表可以为空,也可以有多个返回值。返回值列表必须使用 () 括起来。

函数体是由一系列语句组成的代码块,用于实现函数的功能。函数体必须使用 {} 括起来。

以下是一些函数的示例:

// 定义一个无参数无返回值的函数
func hello() {
    fmt.Println("Hello, world!")
}

// 定义一个有一个参数无返回值的函数
func greet(name string) {
    fmt.Println("Hello, " + name)
}

// 定义一个有两个参数有一个返回值的函数
func add(x, y int) int {
    return x + y
}

// 定义一个有两个参数有两个返回值的函数
func swap(x, y string) (string, string) {
    return y, x
}

// 定义一个有可变参数有一个返回值的函数
func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

// 定义一个有命名返回值的函数
func divide(x, y int) (quo, rem int) {
    quo = x / y
    rem = x % y
    return // 省略返回值列表,直接返回命名返回值
}