1. 变量
变量就是一个有名字的数据。你可以先把变量想象成一个贴着标签的收纳盒:
- 变量名是盒子上的标签;
- 变量值是盒子里保存的数据;
- 数据类型决定这个盒子适合保存哪一类数据。
声明写法:
go
var city string = "北京" // 完整写法
city := "北京" // 简短写法,Go 自动推导类型
1. 1 变量声明
Go 是静态类型语言,变量类型在编译期确定。类型可以显式声明,也可以由编译器根据初始化表达式推导。
1.1.1 使用 var 声明变量
var 是 Go 中声明变量的关键字。var 可用于包级和函数内。
- 声明变量时明确指定类型和初始值: 明确:变量叫什么、是什么类型、初始值是什么。
csharp
var name string = "张三"
var age int = 18
- 声明变量时指定类型,但先不赋值: 暂时不提供初始值,变量仍然有确定的值,即给它们设置对应类型的零值。
go
var name string
var age int
var height float64
var isStudent bool
- 使用
var,让 Go 根据初始值推断类型: 根据右侧初始值,推断变量应该使用的类型。
ini
var name = "张三"
var age = 18
var height = 1.75
var isStudent = true
1.1.2 短变量声明
使用name := "张三" 可以不写类型。 Go 省略的是类型的书写 ,而不是变量的类型。变量仍然有明确的类型,是由 Go 根据右边的值推断出来。 := ****只能用于函数内 ,不能直接在包级别这样写 。
go
package main
var name string = "张三"
package main
import"fmt"
func main() {
name := "张三"
age := 18
height := 1.75
isStudent := true
fmt.Printf("name 的类型:%T\n", name)
fmt.Printf("age 的类型:%T\n", age)
fmt.Printf("height 的类型:%T\n", height)
fmt.Printf("isStudent 的类型:%T\n", isStudent)
}
// 输出:
name 的类型:string
age 的类型:int
height 的类型:float64
isStudent 的类型:bool
1.2 匿名变量
用下划线可以表示不需要某一个变量。未使用的变量是无法通过编译的,当你不需要某一个变量时,就可以使用下划线_代替。
go
for _, value := range values {
// 只关心值
}
for index, value := range values {
// 同时关心下标和值
}
1.3 变量比较和逻辑运算符
| 运算符 | 含义 | 示例 |
|---|---|---|
== |
等于 | age == 18 |
!= |
不等于 | name != "" |
> |
大于 | score > 60 |
< |
小于 | guess < answer |
>= |
大于或等于 | age >= 18 |
<= |
小于或等于 | count <= 10 |
&& |
并且,两个条件都为真 | age >= 18 && hasID |
! |
取反 | !isFinished |
2. 数据类型
2.1 基础数据类型
| 类型 | 说明 | 例子 |
|---|---|---|
| string | 字符串 | "你好" |
| int | 整数 | 18, -3, 0 |
| float64 | 浮点数 | 3.14, 0.5 |
| bool | 布尔值 | true, false |
| byte | 一个字节,本质是 uint8 | 65, byte('A') |
| \[\]byte | 字节切片,常用于文件读写、JSON 处理 | []byte("hello") |
2.1.1 字符串
用于保存文本,通常是 UTF-8 文本。
csharp
var name string = "张三"
len(s)返回字节长度,不是字符数 。for range遍历字符串时按 rune 解码。
go
s := "Go语言"
fmt.Println(len(s)) // 字节长度
fmt.Println([]rune(s)) // 按 Unicode 码点处理
for i, r := range s {
fmt.Printf("%d: %c\n", i, r) //
}
// 输出:
8
[71 111 35821 35328]
0: G
1: o
2: 语
5: 言
- G:1字节、 o:1字节、语:3 字节、言:3 字节。总共
1 + 1 + 3 + 3 = 8。
'G'的码点是71,'o'的码点是111,'语'的码点是35821,'言'的码点是35328。
- i 是字节索引,不是字符索引 。
2.1.2 整型
Go 同时提供有符号整数和无符号整数。每种整数类型都决定了取值范围、是否带符号,以及是否适合位运算或底层数据处理。
| 类型 | 说明 |
|---|---|
| int8 / int16 / int32 / int64 | 固定位宽有符号整数,分别为 8、16、32、64 bit |
| uint8 / uint16 / uint32 / uint64 | 固定位宽无符号整数,所有 bit 都用于表示非负数 |
| int / uint | 与平台相关,通常是 32 或 64 位;int 是最常用整数类型 |
| uintptr | 足以保存指针值的无符号整数,主要用于 unsafe 或底层编程 |
| byte | uint8 的别名,常用于强调"原始字节"语义 |
| rune | int32 的别名,常用于表示 Unicode 码点 |
2.1.3 浮点数
Go 提供两种浮点数类型:float32 和 float64。默认浮点字面量通常推导为 float64。
go
var f float64 = 3.14159
fmt.Println(f)
- 浮点数适合表示近似值,不适合直接用于金额、结算等需要精确小数的场景。
- 浮点数遵循 IEEE 754,存在精度误差,判断相等时不能直接用 ==,而要判断差值是否在一个足够小的范围内。
css
a := 0.1 + 0.2
fmt.Println(a == 0.3) // false
fmt.Println(math.Abs(a-0.3) < 1e-9) // true
- 浮点数还有几个特殊值:正负无穷和 NaN。NaN 与任何值比较都为 false,包括它自己,可用 math.IsNaN 判断。
scss
fmt.Println(math.Inf(1)) // +Inf
z := math.NaN()
fmt.Println(z == z) // false
fmt.Println(math.IsNaN(z)) // true
2.1.4 布尔型
布尔类型 bool 只有两种值:true、false 。它适合表示"是或否""开启或关闭""成功或失败"等状态。
- Go 不允许把数字自动当作布尔值,
if 1 {}这类写法会编译失败。
- 布尔表达式支持短路求值:&& 在左侧为 false 时不再计算右侧,|| 在左侧为 true 时不再计算右侧。这一特性常用于 nil 判断与调用保护,避免空指针 panic。
2.2 派生数据类型
| 类型 | 例子 |
|---|---|
| 数组 | [5]int,长度为 5 的整型数组 |
| 切片 | []float64,64 位浮点数切片 |
| 映射表 | map[string]int,键为字符串类型,值为整型的映射表 |
| 结构体 | type Gopher struct{},Gopher 结构体 |
| 指针 | *int,一个整型指针。 |
| 函数 | type f func(),一个没有参数,没有返回值的函数类型 |
| 接口 | type Gopher interface{},Gopher 接口 |
| 通道 | chan int,整型通道 |
3. 零值
即使声明变量时没有提供初始值,Go 也会给变量一个默认值。这个默认值叫作零值。
常见基础类型的零值如下:
| 类型 | 零值 | 示例 |
|---|---|---|
int |
0 |
var age int |
float64 |
0 |
var height float64 |
string |
""(空字符串) |
var name string |
bool |
false |
var isStudent bool |
| 指针、切片、映射、通道、函数、接口 | nil |
`` |
| 数组和结构体的零值 | 由元素或字段的零值组成 | `` |
4. 常量
const 是声明常量的关键字,表示不应改变的固定值。与变量不同,常量声明后不能再被重新赋值。
c
const name string = "Jack" // 字面量
const numExpression = (1+2+3) / 2 % 100 + num // 常量表达式
- 批量声明常量可以用()括起来以提升可读性
ini
const (
Count = 1
Name = "Jack"
)
- 在同一个常量分组中,在已经赋值的常量后面的常量可以不用赋值,其值默认就是前一个的值
c
const (
A = 1
B // 1
C // 1
D // 1
E // 1
)
4.1 iota
iota是一个内置的常量标识符,通常用于表示一个常量声明中的无类型整数序数。
go
const iota = 0
const (
Num = iota // 0
Num1 // 1
Num2 // 2
Num3 // 3
Num4 // 4
)
const (
Num = iota*2 // 0
Num1 // 2
Num2 // 4
Num3 // 6
Num4 // 8
)
2.2 枚举
Go 语言没有为枚举单独设计一个数据类型,不像其它语言通常会有一个enum来表示。一般在 Go 中,都是通过自定义类型 + const + iota 来实现枚举。
go
type Season uint8
const (
Spring Season = iota
Summer
Autumn
Winter
)