Go 语言入门指南:基础语法和常用特性解析丨青训营

102 阅读10分钟

Go语言(也称为Golang)是一门较新的编程语言,由Google开发,以其简洁性、并发性和高效性而闻名。本篇技术笔记旨在为初学者提供Go语言的入门指南,涵盖了基础语法和常用特性,并包含了示例代码和注释。

一、Hello, World!

众所周知,Hello, World是所有语言世界的大门,接下来我们便敲响Go语言世界的大门。

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

package main

这是Go语言中的包声明语句。包是一个代码文件的集合,用于组织、模块化和重用代码。main包是一个特殊的包,用于指示这个Go文件是一个可执行程序的入口点。

import "fmt"

这是导入其他包的语句。在这个例子中,我们导入了名为fmt的包,它提供了格式化输入和输出的函数。通过导入fmt包,我们可以使用该包中的函数来打印文本。

func main()

这是一个函数声明语句。在Go语言中,每个可执行程序都必须有一个main函数作为入口点。程序从main函数开始执行。

fmt.Println("Hello, World!")

这是一个函数调用语句。在这里,我们调用了fmt包中的Println函数,它用于打印一行文本。我们传递字符串"Hello, World!"作为参数,该字符串将被打印到标准输出。

二、变量声明和使用

当我们在Go语言中编写程序时,变量是一种非常重要的概念。变量用于存储和操作数据,并且在程序中起到临时存储值的作用。在Go语言中,变量的声明和使用遵循一些特定的规则。

1.变量声明和初始化

在Go语言中,可以使用关键字var进行变量声明。变量声明的一般语法是:

var variableName dataType

其中,variableName是变量的名称,dataType是变量的数据类型。 例如,声明一个整数类型的变量可以使用以下语句:

var age int

如果我们要为变量初始化一个初始值,可以使用以下语法:

var variableName dataType = value

例如,声明一个整数类型的变量并初始化为3:

var age int = 3

不过Go语言提供一种简化的方法是使用类型推断,让编译器根据初始值的类型推断出变量的类型:

variableName := value

例如:

age := 10

这里的变量类型将自动推断为整数类型。

2.多个变量声明

在Go语言中,我们可以同时声明多个变量。 例如:

var name, age, height = "Tom", 20, 180

这里我们声明了三个变量name、age和height,并初始化了它们的值。

3.零值

在Go语言中,如果我们声明一个变量但没有显式地为其赋值,那么该变量将被赋予其对应类型的零值。这些零值是根据相应类型的规则确定的。以下是一些常见数据类型的零值:

  • 数值类型(如整数、浮点数)的零值为0。
  • 布尔类型的零值为false。
  • 字符串类型的零值为空字符串""。
  • 指针类型的零值为nil。
  • 结构体类型的零值为各字段类型的零值。

例如:

var num int     // num的零值为0
var isTrue bool // isTrue的零值为false

4.变量赋值和使用

在Go语言中,我们可以使用赋值运算符=将值赋给变量。例如:

age := 25

我们也可以对已经声明的变量进行赋值。例如:

var height int
height = 180

三、条件语句和循环

Go语言中条件语句和循环是非常重要的控制结构,它们允许我们根据条件执行不同的代码块,并在需要时重复执行一段代码。

1.条件语句

在Go语言中,条件语句用于根据不同的条件执行不同的代码块。最常见便是If语句,其语法与c语言大同小异。例如:

package main
import "fmt" 
func main() {
    age := 20 
    if age >= 18 
    { fmt.Println("You are an adult") }
}

2.循环

循环允许我们重复执行同一段代码多次,直到满足退出条件为止。在Go语言中,有以下几种类型的循环:

For循环

for循环在循环开始之前会执行一次初始化语句,然后判断循环条件,如果条件为真,则执行循环体代码块,然后执行循环后的更新语句。 例如:以下是使用for循环打印数字1到5

package main

import "fmt"

func main() {
    for i := 1; i <= 5; i++ {
        fmt.Println(i)
    }
}

这段代码将输出数字1到5,每行打印一个数字。循环变量i初始化为1,然后在每次循环中递增1,直到达到5为止。在每次循环中,使用fmt.Println()函数打印当前的i值。

While循环

Go语言中没有while关键字,但可以通过使用for循环的变体来实现相同的功能。通过省略初始化语句和更新语句,可以创建一个类似于while循环的结构。例如:

package main

import "fmt"

func main() {
    counter := 1
    for counter <= 5 {
        fmt.Println(counter)
        counter++
    }
}

这段代码将输出数字1到5,类似于使用while循环的效果。循环开始前将counter初始化为1,然后在每次循环中打印counter的值并将其递增1,直到counter的值大于5时结束循环。

Range循环

range关键字用于遍历数组、切片、映射或通道中的元素。它返回索引和对应的值。例如:

numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
  fmt.Println("Index:", index, "Value:", value)
}

上述是Go语言中条件语句和循环的基本用法。它们使我们能够根据条件执行不同的代码块,并重复执行特定的代码。对于更复杂的情况,我们还可以使用嵌套条件语句和循环结构。确保使用适当的条件和循环来实现预期的逻辑,不过我们应该注意的是避免无限循环。

四、数组与切片

当我们在Go语言中处理数据时,数组(Array)和切片(Slice)是两个基本且常用的数据结构。它们都可以用于存储一系列相同类型的元素,但在使用方式和功能上有一些区别。

1.数组(Arrays)

定义和初始化数组

数组是一个固定大小的、连续的数据结构,它的大小在创建时就确定,并且不可更改。在Go语言中,可以使用以下方式定义和初始化数组:

var arr [size]dataType

arr := [size]dataType{e1, e2, ..., eN}

其中,size是数组的大小,dataType是数组中元素的数据类型,e1, e2, ..., eN是初始化数组时指定的元素值。 例如:

var numbers [5]int
numbers = [5]int{1, 2, 3, 4, 5}

访问数组元素

可以使用索引访问数组中的元素。数组的索引从0开始,最大索引为size-1。 例如:

fmt.Println(numbers[0]) // 输出第一个元素

数组长度和遍历

可以使用内置函数len()获取数组的长度,并可以使用for循环遍历数组中的元素。

length := len(arr)

for index, value := range arr {
  // 使用index和value进行操作
}

2.切片(Slices)

定义和初始化切片

切片是对数组的抽象,它提供了一种动态大小的、灵活的方式来处理数据。在Go语言中,可以使用以下方式定义和初始化切片:

var slice []dataType

slice := []dataType{e1, e2, ..., eN}

其中,dataType是切片中元素的数据类型,e1, e2, ..., eN是初始化切片时指定的元素值。 例如:

var numbers []int
numbers = []int{1, 2, 3, 4, 5}

访问切片元素

和数组类似,可以使用索引访问切片中的元素。

element = slice[index]

例如:

fmt.Println(numbers[0]) // 输出第一个元素

切片长度和容量:

切片具有长度(len)和容量(cap)的概念。切片的长度是指当前元素的个数,容量是指切片底层数组的大小。可以使用内置函数len()和cap()分别获取切片的长度和容量。

length := len(slice)
capacity := cap(slice)

例如:

numbers := []int{1, 2, 3, 4, 5}
length := len(numbers)     // 获取切片长度
capacity := cap(numbers)   // 获取切片容量

切片操作

切片支持动态操作,可以通过一些内置函数对切片进行操作,例如: 添加元素:使用append()函数可以向切片末尾添加元素。

  numbers := []int{1, 2, 3}
  numbers = append(numbers, 4) // 在切片末尾添加元素4

截取切片:使用切片的下标操作可以截取部分切片。 例如:

  numbers := []int{1, 2, 3, 4, 5}
  newSlice := numbers[1:3] // 截取索引1到2的元素形成新的切片

以上是Go语言中数组和切片的基本用法和操作。数组具有固定大小,而切片提供了更灵活的动态大小。切片通过底层数组的引用来保存数据,并且可以根据需要进行拓展。熟练使用数组和切片可以更高效地处理和操作数据。

五、函数和方法

在Go语言中,函数是一等公民,允许将函数作为参数传递给其他函数,也可以将函数作为返回值。同时,Go语言还支持为特定类型定义方法,方法是一种与类型关联的函数。

1.函数(Functions)

在Go语言中,函数是一段代码块,用于执行特定的操作或计算,并可接收参数和返回值。

定义函数

可以使用关键字func来定义一个函数。函数定义由函数名、参数列表和返回值列表组成。

例如:

func add(x int, y int) int {
    return x + y
}

调用函数

使用函数名和参数列表来调用函数,并可以将返回值赋给变量。

例如:

sum := add(2, 3)

函数作为参数和返回值

在Go语言中,函数可以作为参数传递给其他函数,也可以作为返回值。


type operation func(int, int) int

func performOperation(op operation, x int, y int) int {
    return op(x, y)
}

func multiply(x int, y int) int {
    return x * y
}
result := performOperation(multiply, 4, 5)

在上述示例中,operation是一个函数类型,performOperation函数接受一个函数作为参数,并使用传递的函数执行操作。multiply函数作为参数传递给performOperation函数并返回结果。

2.方法(Methods)

方法是一种与特定类型关联的函数。在Go语言中,可以为自定义类型定义方法,以便在该类型的实例上执行特定操作。

定义方法

定义方法时,需要在函数名前面加上与之关联的类型。

例如:

type Rectangle struct {
    width  int
    height int
}

func (rect Rectangle) area() int {
    return rect.width * rect.height
}

调用方法

使用类型的实例变量来调用方法。

例如:

rectangle := Rectangle{width: 10, height: 5}
area := rectangle.area()

在上述示例中,我们定义了一个类型Rectangle和一个方法area(),该方法计算矩形的面积。通过创建Rectangle的实例,并使用实例变量调用方法来计算矩形的面积。

本篇技术笔记涵盖了Go语言的基础语法和常用特性,包括变量声明、条件语句、循环、数组、切片、函数、方法。希望能为Go入门的同学们带来帮助!