Go 语言基础:变量与常量
📋 目录
- [Go 语言基础:变量与常量](#Go 语言基础:变量与常量)
- [📋 目录](#📋 目录)
- [🔑 变量](#🔑 变量)
- [📖 前言](#📖 前言)
- [📝 变量定义方法](#📝 变量定义方法)
- [1. var 定义](#1. var 定义)
- [2. 一次定义多个变量](#2. 一次定义多个变量)
- [3. 类型推导式](#3. 类型推导式)
- [4. 短变量声明法](#4. 短变量声明法)
- [5. 匿名变量](#5. 匿名变量)
- [🔢 变量的初始化](#🔢 变量的初始化)
- [📄 fmt 包](#📄 fmt 包)
- [📖 前言](#📖 前言)
- [🖨️ Print 和 Println 的区别](#🖨️ Print 和 Println 的区别)
- [📋 Println 和 Printf 的区别](#📋 Println 和 Printf 的区别)
- [🎯 常用占位符](#🎯 常用占位符)
- [📌 常量](#📌 常量)
- [📖 基本定义](#📖 基本定义)
- [🔢 const 结合 iota 的使用](#🔢 const 结合 iota 的使用)
- [iota 基本概念](#iota 基本概念)
- [iota 高级用法](#iota 高级用法)
- [📏 命名规则](#📏 命名规则)
- [💡 最佳实践](#💡 最佳实践)
🔑 变量
📖 前言
在程序运行过程中,数据都保存在内存中。当我们想要在代码中操作某个数据时,需要在内存中找到这个变量。如果直接通过内存地址操作变量,代码的可读性会很差且容易出错。因此,我们使用变量来保存数据的内存地址,通过变量名就能找到内存中对应的数据。
📝 变量定义方法
1. var 定义
基本语法:
go
var 变量名 类型 = 表达式
示例:
go
package main
import "fmt"
func main() {
var name string = "zhangsan"
var age int = 25
var height float64 = 175.5
fmt.Printf("姓名: %s, 年龄: %d, 身高: %.1f\n", name, age, height)
}
2. 一次定义多个变量
① 默认统一类型
go
package main
import "fmt"
func main() {
// var 变量名,变量名 类型
// 没有赋值,输出为空值
var username, sex string
fmt.Printf("username=%s, sex=%s\n", username, sex)
// 赋值后输出
username = "张三"
sex = "男"
fmt.Printf("username=%s, sex=%s\n", username, sex)
}
输出:
username=, sex=
username=张三, sex=男
② 分别指定类型
go
package main
import "fmt"
func main() {
var (
name string = "张三"
sex string = "男"
age int = 15
)
fmt.Printf("name=%s, sex=%s, age=%d\n", name, sex, age)
}
输出:
name=张三, sex=男, age=15
3. 类型推导式
Go 语言可以根据赋值自动推导变量类型:
go
package main
import "fmt"
func main() {
var name = "张三" // 自动推导为 string
var age = 25 // 自动推导为 int
var score = 95.5 // 自动推导为 float64
var isStudent = true // 自动推导为 bool
fmt.Printf("%T: %v\n", name, name)
fmt.Printf("%T: %v\n", age, age)
fmt.Printf("%T: %v\n", score, score)
fmt.Printf("%T: %v\n", isStudent, isStudent)
}
4. 短变量声明法
在函数内部 ,可以使用更简略的 :=
方式声明并初始化变量。
语法:
go
变量名 := 表达式
特点:
- ✅ 只能用于声明局部变量
- ❌ 不能用于全局变量的声明
- ⚡ 更加简洁高效
示例:
go
package main
import "fmt"
// a := 100 // ❌ 非法操作,不能在函数外使用
func main() {
// ✅ 合法使用
name := "张三"
age := 25
name, sex := "李四", "女" // 多重赋值
fmt.Printf("name=%s, age=%d, sex=%s\n", name, age, sex)
}
5. 匿名变量
在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量 。匿名变量用下划线 _
表示。
特点:
- 🚫 不占用命名空间
- 💾 不分配内存
- 🔄 匿名变量之间不存在重复声明
- 🎯 多用于占位,表示忽略值
示例:
go
package main
import "fmt"
func GetInformation() (string, int) {
return "李四", 23
}
func main() {
// 获取所有返回值
name, age := GetInformation()
fmt.Printf("name=%s, age=%d\n", name, age)
// 只要姓名,忽略年龄
name, _ = GetInformation()
fmt.Printf("name=%s\n", name)
// 只要年龄,忽略姓名
_, age = GetInformation()
fmt.Printf("age=%d\n", age)
}
输出:
name=李四, age=23
name=李四
age=23
🔢 变量的初始化
Go 语言在声明变量时,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值(零值):
数据类型 | 默认值 |
---|---|
整型(int, int8, int16, int32, int64) | 0 |
无符号整型(uint, uint8, uint16, uint32, uint64) | 0 |
浮点型(float32, float64) | 0.0 |
字符串(string) | "" (空字符串) |
布尔型(bool) | false |
切片(slice) | nil |
映射(map) | nil |
通道(chan) | nil |
函数(func) | nil |
指针(pointer) | nil |
接口(interface) | nil |
示例:
go
package main
import "fmt"
func main() {
var a int
var b float64
var c string
var d bool
var e []int
fmt.Printf("int 默认值: %d\n", a)
fmt.Printf("float64 默认值: %f\n", b)
fmt.Printf("string 默认值: '%s'\n", c)
fmt.Printf("bool 默认值: %t\n", d)
fmt.Printf("slice 默认值: %v\n", e)
}
📄 fmt 包
📖 前言
Go 中要打印一个值需要引入 fmt
包。fmt
包提供了一些常见的打印数据的方法,如:Print
、Println
、Printf
。在实际开发中,后两个使用得非常多。
go
import "fmt"
🖨️ Print 和 Println 的区别
主要区别:
- 间隔 :
Println
在多个值之间有空格,Print
没有 - 换行 :
Println
会自动换行,Print
不会
示例:
go
package main
import "fmt"
func main() {
fmt.Println("go", "python", "java") // 有空格,自动换行
fmt.Print("go", "python", "java") // 无空格,不换行
fmt.Print("Print不会换行") // 继续在同一行
fmt.Println("这里换行了") // 换行
}
输出:
go python java
gopythonjavaprint不会换行这里换行了
📋 Println 和 Printf 的区别
Printf
是格式化输出 ,在很多场景下比 Println
更方便和灵活。
示例:
go
package main
import "fmt"
func main() {
A := 10
B := 20
C := 30
// Println 方式
fmt.Println("A=", A, "B=", B, "C=", C)
// Printf 方式(格式化输出)
fmt.Printf("A=%d, B=%d, C=%d\n", A, B, C)
}
输出:
A= 10 B= 20 C= 30
A=10, B=20, C=30
🎯 常用占位符
占位符 | 说明 | 示例 |
---|---|---|
%d |
十进制整数 | fmt.Printf("%d", 42) → 42 |
%o |
八进制整数 | fmt.Printf("%o", 42) → 52 |
%x |
十六进制整数(小写) | fmt.Printf("%x", 42) → 2a |
%X |
十六进制整数(大写) | fmt.Printf("%X", 42) → 2A |
%f |
浮点数 | fmt.Printf("%f", 3.14) → 3.140000 |
%.2f |
保留2位小数 | fmt.Printf("%.2f", 3.14159) → 3.14 |
%s |
字符串 | fmt.Printf("%s", "hello") → hello |
%c |
字符 | fmt.Printf("%c", 65) → A |
%t |
布尔值 | fmt.Printf("%t", true) → true |
%v |
默认格式 | fmt.Printf("%v", 42) → 42 |
%T |
类型 | fmt.Printf("%T", 42) → int |
%p |
指针地址 | fmt.Printf("%p", &a) → 0xc000... |
%% |
百分号本身 | fmt.Printf("100%%") → 100% |
📌 常量
📖 基本定义
相对于变量,常量 是恒定不变的值,多用于定义程序运行期间不会改变的那些值。常量的声明和变量声明非常类似,只是把 var
换成了 const
,常量在定义的时候必须赋值。
基本语法:
go
const 常量名 类型 = 值
示例:
go
package main
import "fmt"
func main() {
const PI float64 = 3.14159
const AppName string = "Go学习系统"
const MaxUsers = 1000 // 类型推导
fmt.Printf("圆周率: %f\n", PI)
fmt.Printf("应用名称: %s\n", AppName)
fmt.Printf("最大用户数: %d\n", MaxUsers)
}
批量定义:
go
package main
import "fmt"
func main() {
const (
a = 2.5
b = 3.6
c // 省略值,表示和上面一行的值相同
)
const (
A = 3
B // 值为 3
C // 值为 3
)
fmt.Printf("a=%f\tb=%f\tc=%f\n", a, b, c)
fmt.Printf("A=%d\tB=%d\tC=%d\n", A, B, C)
}
输出:
a=2.500000 b=3.600000 c=3.600000
A=3 B=3 C=3
🔢 const 结合 iota 的使用
iota 基本概念
iota
是 Go 语言的常量计数器,只能在常量的表达式中使用iota
在const
关键字出现时将被重置为 0const
中每新增一行常量声明将使iota
计数一次(可理解为 const 语句块中的行索引)
基本示例:
go
package main
import "fmt"
func main() {
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
fmt.Printf("Sunday: %d\n", Sunday)
fmt.Printf("Monday: %d\n", Monday)
fmt.Printf("Saturday: %d\n", Saturday)
}
iota 高级用法
① 跳过某些值和中间插队:
go
package main
import "fmt"
func main() {
const (
a = iota // 0
b = 1 // 1 (中间插队)
c // 1 (继承上一行的值)
d = 1 // 1 (再次赋值)
e = iota // 4 (恢复 iota,当前行索引为 4)
_ // 5 (跳过)
f // 6 (继续计数)
)
fmt.Printf("a=%d\tb=%d\tc=%d\td=%d\te=%d\tf=%d\n", a, b, c, d, e, f)
}
输出:
a=0 b=1 c=1 d=1 e=4 f=6
② 实际应用示例:
go
package main
import "fmt"
func main() {
// 文件权限
const (
Read = 1 << iota // 1 << 0 = 1
Write // 1 << 1 = 2
Execute // 1 << 2 = 4
)
// 网络协议端口
const (
HTTP = iota + 80 // 0 + 80 = 80
HTTPS // 1 + 80 = 81
FTP // 2 + 80 = 82
)
fmt.Printf("权限 - Read: %d, Write: %d, Execute: %d\n", Read, Write, Execute)
fmt.Printf("端口 - HTTP: %d, HTTPS: %d, FTP: %d\n", HTTP, HTTPS, FTP)
}
输出:
权限 - Read: 1, Write: 2, Execute: 4
端口 - HTTP: 80, HTTPS: 81, FTP: 82
📏 命名规则
🔤 标识符命名规则
- 组成元素:变量名必须由数字、字母、下划线组成
- 开头限制:标识符开头不能是数字
- 关键字限制:标识符不能是保留字和关键字
- 大小写敏感:变量的名字是区分大小写的
- 见名知意:变量名称建议用名词,方法名称建议用动词
✅ 合法的标识符
go
var name string // ✅
var user_name string // ✅
var userName string // ✅
var age18 int // ✅
var _temp float64 // ✅
var π float64 // ✅ 支持 Unicode 字符
❌ 不合法的标识符
go
var 2name string // ❌ 不能以数字开头
var user-name string // ❌ 不能包含 -
var class string // ❌ class 是关键字
var func string // ❌ func 是关键字
📚 Go 语言关键字(25个)
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
🎯 命名约定
① 驼峰命名法:
go
// 小驼峰(私有)
var userName string
var maxCount int
// 大驼峰(公有,可导出)
var UserName string
var MaxCount int
② 常见命名模式:
go
// 常量:全大写,下划线分隔
const MAX_USER_COUNT = 1000
const API_VERSION = "v1.0"
// 包级常量:大驼峰
const DefaultTimeout = 30
// 布尔变量:is/has/can 前缀
var isReady bool
var hasPermission bool
var canAccess bool
// 计数器:count/num 后缀
var userCount int
var pageNum int
💡 最佳实践
🎯 变量使用建议
- 就近声明:在变量使用的地方附近声明
- 零值可用:利用 Go 的零值特性,减少不必要的初始化
- 短变量声明 :在函数内部优先使用
:=
- 批量声明:相关变量可以批量声明
🔒 常量使用建议
- 配置参数:将不变的配置定义为常量
- 魔法数字:避免在代码中直接写数字,用常量替代
- 枚举值 :使用
iota
定义枚举类型
📝 代码示例:综合应用
go
package main
import "fmt"
// 全局常量
const (
AppName = "Go学习系统"
AppVersion = "1.0.0"
)
// 状态枚举
const (
StatusPending = iota // 0
StatusRunning // 1
StatusCompleted // 2
StatusFailed // 3
)
func main() {
// 短变量声明
userName := "张三"
userAge := 25
// 批量变量声明
var (
score float64 = 95.5
isVIP bool = true
subjects = []string{"数学", "语文", "英语"}
)
// 匿名变量的使用
info, _ := getUserInfo(userName)
// 格式化输出
fmt.Printf("=== %s %s ===\n", AppName, AppVersion)
fmt.Printf("用户信息: %s\n", info)
fmt.Printf("姓名: %s, 年龄: %d, 分数: %.1f\n", userName, userAge, score)
fmt.Printf("VIP用户: %t\n", isVIP)
fmt.Printf("学习科目: %v\n", subjects)
fmt.Printf("当前状态: %d\n", StatusRunning)
}
func getUserInfo(name string) (string, error) {
return fmt.Sprintf("用户 %s 的详细信息", name), nil
}
🎉 恭喜!您已掌握 Go 语言变量和常量的核心概念,继续加油学习!