Go 基础语法

Go 由 Google 开发,语法简洁、编译速度快、天生支持并发,非常适合后端开发和系统编程。本站所有的算法代码都配有 Go 版本,你学完基础之后可以在刷题过程中熟悉和应用这门语言。

下面我们就开始学习 Go 语言的基础语法。

Hello World 与程序结构

先看一个最简单的 Go 程序:

拆解一下这个结构:

package main    // 声明包名,可执行程序必须是 main 包

import "fmt"    // 引入标准库的 fmt 包,用于格式化输入输出

func main() {   // 程序入口函数
    // 你的代码写在这里
}

package main 声明这是一个可执行程序。Go 用包(package)来组织代码,main 包是特殊的——它告诉编译器"这是一个可以直接运行的程序"。

import "fmt" 引入了标准库的 fmt 包,提供了 PrintlnPrintf 等输入输出函数。引入多个包时可以用括号:

import (
    "fmt"
    "math"
)

func main() 是程序的入口函数,程序运行时自动执行这个函数。

Go 有几个语法特点:不需要分号,编译器会自动在行尾加上;左花括号必须跟在语句后面,不能另起一行,否则编译报错。比如下面这样写是不行的:

// 编译报错!左花括号不能另起一行
func main()
{
}

标准输出

Go 的输出函数都在 fmt 包里,最常用的有三个:

常用的格式化占位符:

占位符说明示例
%d整数fmt.Printf("%d", 42)
%f浮点数fmt.Printf("%f", 3.14)
%s字符串fmt.Printf("%s", "hello")
%c字符fmt.Printf("%c", 'A')
%v万能格式(任意类型)fmt.Printf("%v", anything)
%t布尔值fmt.Printf("%t", true)

Println 日常用得最多,Printf 在需要精确控制格式时使用。

读取输入

fmt.Scan 用来从控制台读取输入:

fmt.Scan 的关键点:变量前面要加 & 符号,表示把读到的值存到这个变量的地址里。Scan 以空格和换行作为分隔符,适合读取单个值或空格分隔的多个值。

如果需要读取一整行(包括空格),可以用 bufio.Scanner

bufio.NewScanner(os.Stdin) 创建一个从标准输入读取的扫描器,scanner.Scan() 读取一行,scanner.Text() 获取读到的文本内容。

循环读取到输入结束

有些题目的输入数据量不确定,需要一直读取到输入结束(EOF)。用 fmt.Scan 的返回值来判断:

当输入结束时,fmt.Scan 会返回一个非 nil 的错误(io.EOF),循环自动退出。

变量与数据类型

基本类型

Go 语言最常用的数据类型:

类型说明示例
int整数(平台相关,通常 64 位)var a int = 10
int6464 位整数var b int64 = 999
float64浮点数(小数)var c float64 = 3.14
byte字节(等同于 uint8)var d byte = 'A'
bool布尔值var e bool = true
string字符串var f string = "hello"

:= 短声明是 Go 中最常用的变量声明方式,它会根据右边的值自动推断类型,写起来很简洁。不过 := 只能在函数内部使用,包级别的变量必须用 var

Go 有一个很严格的规定:声明了的变量必须使用,否则编译报错。这是为了保持代码整洁,但刚开始可能会觉得有点烦。如果临时不需要某个值,可以用 _(下划线)来忽略。

常量

const 声明常量,声明后不能修改:

const MaxSize = 100
const Pi = 3.14159

类型转换

Go 的类型转换必须是显式的,不会像某些语言那样自动转换:

特别注意:Go 中即使是 intint64 之间也必须显式转换,不能直接赋值。整数除法 1 / 2 结果是 0,想得到小数就得先转成 float64

运算符

算术运算符

注意 Go 的 ++-- 只能作为独立语句,不能写在表达式里。比如 x = c++ 这样的写法在 Go 里是编译错误的。

比较与逻辑运算符

Go 没有三元运算符(就是其他语言里的 条件 ? 值1 : 值2),只能老老实实写 if-else:

// 其他语言:max = a > b ? a : b
// Go 只能这样写:
var max int
if a > b {
    max = a
} else {
    max = b
}

位运算

位运算在处理二进制相关问题时非常高效。详细的位运算原理可以参考 常用的位操作,这里了解一下基本用法就行:

控制流

条件判断 if / else

Go 的 if 条件不需要括号,这一点和 C/Java 不同:

for 循环

Go 只有 for 一种循环,没有 whiledo-while,但 for 可以写出三种不同的形式:

range 遍历

range 用来遍历数组、切片、字符串等,它会返回索引和值两个变量:

break 和 continue

break 跳出整个循环,continue 跳过当前这轮、进入下一轮:

switch 语句

Go 的 switch 和其他语言不太一样:不需要 break,每个 case 执行完自动终止,不会穿透到下一个。而且一个 case 可以匹配多个值:

Go 的 switch 默认就是 break 的行为,如果你确实想穿透到下一个 case,可以用 fallthrough 关键字,但实际中很少用到。

小结

这篇介绍了 Go 语言的基础语法:程序结构、输入输出、变量类型、运算符和控制流。Go 的语法比较简洁,没有多余的东西,写起来很舒服。

下一篇我们来更深入地讲讲 Go 的 包与导入 机制,包括可见性规则(大小写的讲究)、init() 函数,以及标准库中那些刷题常用的包。