第一章基础知识

6 阅读11分钟

1 Token(词法单元)

Token 是构成 Go 源程序的最基本、不可再分割的语法单元
Go 语言中的 Token 主要分为以下五类:

  1. 关键字(Keyword)
  2. 标识符(Identifier)
  3. 操作符(Operator)
  4. 分隔符(Delimiter)
  5. 字面常量(Literal)

1.1 关键字(Keyword)

1.1.1 定义

关键字是 Go 语言中具有固定语义的保留字
不能作为标识符使用

Go 语言一共有 25 个关键字


1.1.2 关键字分类

(1)程序结构相关

package import

(2)声明相关

var const type func

(3)流程控制

if else switch case default
for range goto

(4)并发相关(Go 特色)

go select

(5)延迟与返回

defer return

(6)接口与结构体

interface struct

(7)数据结构与通道

map chan

1.1.3 Go 语言全部关键字(完整列表)

break      default     func       interface   select
case       defer       go         map         struct
chan       else        goto       package     switch
const      fallthrough if         range       type
continue   for         import     return      var

1.1.4 关键字特点总结

特点说明
数量固定共 25 个
语义固定编译器内置含义
不能自定义不能作为变量、函数名

1.2 标识符(Identifier)

1.2.1 定义

标识符是程序中用来命名各种程序实体的符号,包括:

  • 变量
  • 常量
  • 函数
  • 类型
  • 包名
  • 结构体字段
  • 接口方法等
var count int
func add(a int, b int) int {}
type User struct {}

其中 countaddUser 都是标识符。


1.2.2 标识符命名规则

  1. 只能由以下字符组成:

    • 字母(A–Z, a–z)
    • 数字(0–9)
    • 下划线 _
  2. 不能以数字开头

  3. 区分大小写

  4. 不能与关键字冲突

✅ 合法示例:

name
user1
_total
HTTPServer

❌ 非法示例:

1num     // 数字开头
user-name // 含非法字符
var      // 关键字

1.2.3 标识符的可见性(Go 特有)

Go 使用首字母大小写控制访问权限:

首字母可见性
大写导出(public,包外可见)
小写未导出(private,仅包内)
var Name string   // 包外可访问
var age int       // 仅包内可访问

1.3 操作符(Operator)

1.3.1 定义

操作符用于对操作数执行计算、比较、赋值、逻辑运算等操作。


1.3.2 操作符分类

(1)算术运算符

+  -  *  /  %

(2)关系运算符

==  !=  >  <  >=  <=

(3)逻辑运算符

&&  ||  !

(4)位运算符

&  |  ^  <<  >>  &^

(5)赋值运算符

=   +=  -=  *=  /=  %=  
<<= >>= &=  |=  ^=

(6)其他运算符

&   // 取地址
*   // 指针解引用
<-  // 通道操作符

1.4 分隔符(Delimiter)

1.4.1 定义

分隔符用于分隔程序结构、表达语句边界。


1.4.2 Go 常用分隔符

( )     // 圆括号:函数调用、表达式
[ ]     // 方括号:数组、切片
{ }     // 花括号:代码块、结构体
,       // 逗号:参数、变量分隔
;       // 分号(Go 中多数情况自动插入)
:       // 冒号(switch、map)
.       // 点(包访问、结构体字段)

示例:

func add(a int, b int) int {
    return a + b
}

1.5 字面常量(Literal)

1.5.1 定义

字面常量是源代码中直接表示值的常量。


1.5.2 字面常量分类

(1)整型字面量

10
0
0xff
0b1010

(2)浮点型字面量

3.14
1e10
0.5

(3)字符字面量(rune)

'a'
'中'
'\n'

(4)字符串字面量

"hello"
"Go语言"

原始字符串(反引号):

`line1
line2`

(5)布尔字面量

true false

(6)特殊字面量

nil


1.6 关键字 vs 标识符(对比总结)

对比项标识符关键字
是否可自定义
是否有固定语义
是否可命名变量
数量无限25 个

2 变量和常量

变量和常量用于存储和表示数据,是 Go 程序中最基本的组成部分。


2.1 变量(Variable)

2.1.1 定义

变量是在程序运行过程中,其值可以发生改变的存储单元。
变量在使用前必须先声明


2.1.2 变量的声明方式

(1)标准声明(显式类型)

var a int
var b int = 10

(2)类型推断声明

var c = 20

编译器会根据右值自动推断变量类型。


(3)短变量声明(推荐)

d := 30

⚠️ 注意:

  • 只能在函数内部使用
  • 至少有一个变量是新声明的
x := 10
x, y := 20, 30 // 合法,y 是新变量

(4)批量声明

var (
    a int
    b = 10
    c string = "go"
)

2.1.3 变量的作用域

(1)局部变量

定义在函数或代码块中,仅在其作用域内有效。

func test() {
    x := 10
    fmt.Println(x)
}

(2)全局变量

定义在函数外,整个包内可见。

var g = 100

2.1.4 变量的零值(Zero Value)

Go 中变量声明但未初始化时,会自动赋予零值

类型零值
数值类型0
布尔类型false
字符串""
指针 / 切片 / map / channelnil
var i int       // 0
var s string    // ""
var p *int      // nil

2.1.5 变量命名规范

  • 使用有意义的英文单词
  • 驼峰命名法(camelCase)
  • 遵循 首字母大小写控制可见性规则
var userName string
var Age int    // 导出变量

2 变量和常量

变量和常量用于存储和表示数据,是 Go 程序中最基本的组成部分。


2.1 变量(Variable)

2.1.1 定义

变量是在程序运行过程中,其值可以发生改变的存储单元。
变量在使用前必须先声明


2.1.2 变量的声明方式

(1)标准声明(显式类型)

var a int
var b int = 10

(2)类型推断声明

var c = 20

编译器会根据右值自动推断变量类型。


(3)短变量声明(推荐)

d := 30

⚠️ 注意:

  • 只能在函数内部使用
  • 至少有一个变量是新声明的
x := 10
x, y := 20, 30 // 合法,y 是新变量

(4)批量声明

var (
    a int
    b = 10
    c string = "go"
)

2.1.3 变量的作用域

(1)局部变量

定义在函数或代码块中,仅在其作用域内有效。

func test() {
    x := 10
    fmt.Println(x)
}

(2)全局变量

定义在函数外,整个包内可见。

var g = 100

2.1.4 变量的零值(Zero Value)

Go 中变量声明但未初始化时,会自动赋予零值

类型零值
数值类型0
布尔类型false
字符串""
指针 / 切片 / map / channelnil
var i int       // 0
var s string    // ""
var p *int      // nil

2.1.5 变量命名规范

  • 使用有意义的英文单词
  • 驼峰命名法(camelCase)
  • 遵循 首字母大小写控制可见性规则

复制

var userName string
var Age int    // 导出变量

2.2 常量(Constant)

2.2.1 定义

常量是在程序运行期间,其值不可改变的量。
常量使用 const 关键字声明。


2.2.2 常量的声明方式

(1)单个常量声明

const PI = 3.14
const Max int = 100

(2)批量常量声明

const (
    A = 1
    B = 2
    C = 3
)

2.2.3 无类型常量(Go 特有)

Go 中的常量可以没有显式类型,在使用时再确定类型。

const x = 10
var y int = x
var z float64 = x

✅ 提高了常量的灵活性。


2.2.4 iota 常量生成器

iota 是 Go 中用于生成枚举常量的关键字。

const (
    A = iota // 0
    B        // 1
    C        // 2
)

iota 常见用法

const (
    KB = 1 << (10 * iota)
    MB
    GB
)

2.2.5 常量的特点

特点说明
值不可修改编译期确定
可无类型使用时决定类型
不占运行期内存编译期替换

2.3 变量 vs 常量 对比

对比项变量常量
关键字var / :=const
是否可修改
是否有零值❌(必须初始化)
是否支持类型推断
运行期占内存

2.4 使用场景总结

✅ 使用变量的场景

  • 运行过程中会变化的数据
  • 用户输入、计算结果、状态值
count := 0
count++

✅ 使用常量的场景

  • 固定不变的值
  • 配置项、枚举值、数学常量
const MaxRetry = 3

3 基本数据类型

基本数据类型用于描述变量或常量所能存储的数据种类,是 Go 语言类型系统的基础。


3.1 数值类型(Numeric Types)

数值类型用于表示整数和浮点数


3.1.1 整型(Integer)

(1)有符号整型

类型位数取值范围
int88−27∼27−1−27∼27−1
int1616−215∼215−1−215∼215−1
int3232−231∼231−1−231∼231−1
int6464−263∼263−1−263∼263−1
int平台相关32 或 64 位

(2)无符号整型

类型位数取值范围
uint880∼28−10∼28−1
uint16160∼216−10∼216−1
uint32320∼232−10∼232−1
uint64640∼264−10∼264−1
uint平台相关32 或 64 位

(3)特殊整型

类型说明
byteuint8 的别名,常用于表示字节
runeint32 的别名,表示 Unicode 字符
var b byte = 65
var r rune = '中'

3.1.2 浮点型(Floating-point)

类型位数精度
float3232单精度
float6464双精度(默认)
var f1 float32 = 3.14
var f2 = 3.1415926 // 默认 float64

3.1.3 复数类型(Complex)

类型说明
complex64由 float32 构成
complex128由 float64 构成
var c1 complex64 = 1 + 2i
var c2 = complex(3, 4)

3.2 布尔类型(Boolean)

3.2.1 定义

布尔类型用于表示逻辑真假

var ok bool = true

3.2.2 特点

  • 只有两个值:truefalse
  • 不能与整数相互转换
if ok {
    fmt.Println("true")
}

3.3 字符类型(Character)

Go 没有单独的 char 类型,字符使用 rune 表示。

var ch rune = 'A'
var zh rune = '中'

✅ 本质是 Unicode 编码的整数。


3.4 字符串类型(String)

3.4.1 定义

字符串是由 字节序列 组成的不可变数据类型。 字符串是由 字节序列 组成的不可变数据类型。

var s string = "Hello Go"

3.4.2 字符串表示方式

(1)解释型字符串(双引号)

s1 := "hello\nworld"

支持转义字符。


(2)原始字符串(反引号)

s2 := `hello
world`

不支持转义,常用于多行文本。


3.4.3 字符串特点

  • 字符串不可修改
  • 可通过索引访问字节
  • 中文字符占多个字节
s := "Go语言"
fmt.Println(len(s)) // 字节长度

4 复合数据类型

复合数据类型是由基本数据类型组合而成的数据结构,用于表示更复杂的数据关系。
Go 语言提供了多种复合数据类型,以提高程序的表达能力和开发效率。


4.1 数组(Array)

4.1.1 定义

数组是由相同类型元素组成的、长度固定的有序集合。
数组长度是其类型的一部分

var a [3]int = [3]int{1, 2, 3}

4.1.2 数组的声明方式

var a [5]int
var b = [3]int{1, 2, 3}
var c = [...]int{4, 5, 6}

4.1.3 数组的访问与遍历

fmt.Println(b[0])

for i := 0; i < len(b); i++ {
    fmt.Println(b[i])
}

for index, value := range b {
    fmt.Println(index, value)
}

4.1.4 数组的特点

  • 长度固定,不能动态扩展
  • 值类型,赋值会发生拷贝
  • 适合表示长度确定的数据集合

4.2 切片(Slice)

4.2.1 定义

切片是对数组的动态引用,长度可变,是 Go 中最常用的数据结构之一。

s := []int{1, 2, 3}

4.2.2 切片的创建方式

(1)字面量创建

s1 := []int{1, 2, 3}

(2)基于数组创建

arr := [5]int{1, 2, 3, 4, 5}
s2 := arr[1:4]

(3)使用 make 创建

s3 := make([]int, 3, 5)

4.2.3 切片的长度与容量


len(s3) // 长度
cap(s3) // 容量

4.2.4 切片的追加与拷贝

s = append(s, 4, 5)
copy(dst, src)

4.2.5 切片的特点

  • 引用类型
  • 动态扩容
  • 底层基于数组实现

4.3 映射(Map)

4.3.1 定义

映射(map)是一种键值对形式的数据结构。

m := map[string]int{
    "go": 1,
    "java": 2,
}

4.3.2 map 的创建方式

m1 := make(map[string]int)

4.3.3 map 的基本操作

m["python"] = 3
delete(m, "java")

value, ok := m["go"]

4.3.4 map 的特点

  • 引用类型
  • key 唯一
  • 无序
  • 未初始化的 map 为 nil

4.4 结构体(Struct)

4.4.1 定义

结构体用于将多个不同类型的数据组合成一个整体。

type User struct {
    Name string
    Age  int
}

4.4.2 结构体的创建与使用

u := User{
    Name: "Tom",
    Age:  20,
}

fmt.Println(u.Name)

4.4.3 结构体指针

p := &User{Name: "Alice", Age: 25}
fmt.Println(p.Age)

4.4.4 结构体的特点

  • 值类型
  • 支持嵌套
  • 是面向对象的基础

4.5 指针(Pointer)

4.5.1 定义

指针用于存储变量的内存地址。

var p *int
x := 10
p = &x

4.5.2 指针操作

fmt.Println(*p) // 解引用

4.5.3 指针特点

  • 提高性能,避免大对象拷贝
  • 可以修改函数外部变量
  • 零值为 nil

4.6 通道(Channel)

4.6.1 定义

通道是 Go 中用于 goroutine 之间通信 的数据类型。

ch := make(chan int)

4.6.2 通道的基本操作


ch <- 10   // 发送
x := <-ch  // 接收

4.6.3 通道的特点

  • 引用类型
  • 支持并发安全通信
  • Go 并发模型的核心

4.7 接口(Interface)

4.7.1 定义

接口定义了一组方法的集合,用于描述行为。

type Reader interface {
    Read() string
}

4.7.2 接口特点

  • 隐式实现
  • 支持多态
  • 面向接口编程

4.8 复合数据类型零值汇总

类型零值
array元素类型零值
slicenil
mapnil
struct字段零值
pointernil
channelnil
interfacenil