命名规则
Go语言的命名规则遵循以下规范:
-
字母或下划线开头:名称必须以字母或下划线开头
-
后续字符:可以是字母、数字或下划线
-
区分大小写 :
Name
和name
是不同的标识符 -
关键字不能作为标识符 :如
func
,var
,package
等 -
推荐使用驼峰命名法:
-
导出名称(首字母大写):
UserName
-
非导出名称(首字母小写):
userName
-
变量
变量声明
Go
// 单变量声明
var name string = "John"
// 类型推断
var age = 30
// 多变量声明
var width, height int = 100, 50
// 简短声明(只能在函数内使用)
count := 10
变量默认值
-
数值类型:
0
-
布尔类型:
false
-
字符串:
""
(空字符串) -
指针、函数、接口、slice、channel、map:
nil
全局变量
全局变量是在函数外部声明的变量,可以在整个包内访问(如果首字母大写,则可以在其他包中访问)。
全局变量特点
-
声明在函数体外部
-
生命周期贯穿整个程序运行期间
-
如果首字母大写,可以被其他包访问
-
如果首字母小写,只能在当前包内访问
全局变量示例
Go
package main // 必须声明包名(main包才能直接运行)
import "fmt" // 需要导入fmt包才能使用Println
var global = "我是全局的" // 全局变量
func main() {
fmt.Println(global) // 可以访问
}
局部变量
局部变量是在函数或代码块内部声明的变量,只在声明它们的函数或代码块内有效。
局部变量特点
-
声明在函数或代码块内部
-
生命周期仅限于函数或代码块执行期间
-
只能在声明它们的函数或代码块内访问
-
可以使用简短声明语法
:=
局部变量示例
Go
package main
import "fmt"
func main() {
local := "我是局部的"
fmt.Println(local) // 输出
}
全局变量与局部变量的优先级
当全局变量和局部变量同名时,局部变量会优先被使用:
Go
package main
import "fmt"
// 全局变量 - 在整个包中都可以访问
var globalVar = "我是全局变量"
func printVars() {
// 局部变量 - 只在这个函数内有效
localVar := "我是printVars的局部变量"
fmt.Println("(4) 在printVars函数内 - 局部变量:", localVar)
fmt.Println("(5) 在printVars函数内 - 全局变量:", globalVar) // 可以访问全局变量
// 修改全局变量
globalVar = "在printVars中修改后的全局变量"
fmt.Println("(6) 在printVars函数内 - 修改后的全局变量:", globalVar)
}
func main() {
fmt.Println("(1) main函数开始 - 全局变量:", globalVar)
// 局部变量 - 只在main函数内有效
localVar := "我是main的局部变量"
fmt.Println("(2) main函数内 - 局部变量:", localVar)
fmt.Println("(3) main函数内 - 全局变量:", globalVar)
printVars() // 调用printVars函数
fmt.Println("(7) 回到main函数 - 局部变量:", localVar)
fmt.Println("(8) 回到main函数 - 全局变量:", globalVar) // 全局变量已被修改
// 代码块内的局部变量
{
blockVar := "我是代码块内的局部变量"
fmt.Println("(9) 代码块内 - 块变量:", blockVar)
// fmt.Println(localVar) // 可以访问外层局部变量
}
// fmt.Println(blockVar) // 错误!blockVar在这里不可访问
fmt.Println("(10) 程序结束")
}
常量
常量声明
常量是Go语言中一种固定不变的值,在程序运行期间不能被修改。本教程将详细介绍Go语言中常量的定义、使用和相关特性。
演示代码:
Go
/*
* Go语言常量使用完整示例(修正大整数问题版)
* 包含各种常量定义方式和使用场景
*/
package main
import (
"fmt"
"math"
"math/big"
)
// 1. 基本常量定义
const Pi = 3.14159 // 无类型浮点常量
const AppName = "MyGoApp" // 无类型字符串常量
const MaxRetry = 3 // 无类型整型常量
// 2. 多常量声明(常量组)
const (
StatusOK = 200 // HTTP状态码200
StatusCreated = 201 // HTTP状态码201
StatusError = 500 // HTTP状态码500
)
// 3. 显式类型常量
const MaxUsers int = 1000 // 显式声明为int类型
const Greeting string = "Hello, 世界!" // 显式声明为string类型
const Price float64 = 99.99 // 显式声明为float64类型
// 4. 常量表达式
const (
SecondsPerMinute = 60
SecondsPerHour = SecondsPerMinute * 60 // 基于其他常量计算
SecondsPerDay = SecondsPerHour * 24
)
// 5. iota枚举示例(星期)
const (
Sunday = iota // 0,从0开始
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
// 6. iota位运算示例(文件大小)
const (
_ = iota // 忽略第一个值(0)
KB = 1 << (10 * iota) // 1 << 10 = 1024
MB // 1 << 20 = 1048576
GB // 1 << 30 = 1073741824
)
// 7. 大整数常量处理(修正版)
const (
// 注意:9876543210123456789超过了int64的最大值9223372036854775807
// 解决方案1:使用uint64(如果确定是非负数)
BigNumber uint64 = 9223372036854775807 // 使用int64最大值
// 解决方案2:使用字符串表示更大的数字
HugeNumberStr = "9876543210123456789"
// 解决方案3:使用较小的数字
SmallNumber = 987654321
)
func main() {
// ========== 基本常量使用 ==========
fmt.Println("=== 基本常量 ===")
fmt.Printf("Pi = %.5f\n", Pi)
fmt.Printf("Application: %s\n", AppName)
fmt.Printf("Max retry times: %d\n", MaxRetry)
// ========== 类型化常量使用 ==========
fmt.Println("\n=== 类型化常量 ===")
fmt.Printf("Max users: %d (type: %T)\n", MaxUsers, MaxUsers)
fmt.Printf("Greeting: %s (type: %T)\n", Greeting, Greeting)
fmt.Printf("Price: %.2f (type: %T)\n", Price, Price)
// ========== 常量表达式使用 ==========
fmt.Println("\n=== 常量表达式 ===")
fmt.Printf("Seconds in a day: %d\n", SecondsPerDay)
// ========== iota枚举使用 ==========
fmt.Println("\n=== iota枚举 ===")
fmt.Printf("Wednesday is day %d of the week\n", Wednesday)
// ========== 文件大小常量 ==========
fmt.Println("\n=== 文件大小常量 ===")
fmt.Printf("1GB = %d bytes\n", GB)
// ========== 大整数处理 ==========
fmt.Println("\n=== 大整数处理 ===")
// 使用uint64打印大整数
fmt.Printf("Big number (uint64): %d\n", BigNumber)
// 使用math/big处理超大整数
bigInt := new(big.Int)
bigInt.SetString(HugeNumberStr, 10)
fmt.Printf("Huge number: %s\n", bigInt.String())
// 打印较小的数字
fmt.Printf("Small number: %d\n", SmallNumber)
// ========== 常量运算 ==========
fmt.Println("\n=== 常量运算 ===")
const radius = 5.0
area := Pi * math.Pow(radius, 2)
fmt.Printf("Area of circle with radius %.1f: %.2f\n", radius, area)
// ========== 类型转换 ==========
const temperature = 100 // 无类型整数常量
fTemp := float64(temperature)*1.8 + 32
fmt.Printf("%d°C is %.1f°F\n", temperature, fTemp)
// ========== 常量与变量比较 ==========
fmt.Println("\n=== 常量与变量比较 ===")
var userCount = 850
if userCount < MaxUsers {
fmt.Printf("User count (%d) is below maximum (%d)\n", userCount, MaxUsers)
} else {
fmt.Printf("User count (%d) has reached maximum (%d)\n", userCount, MaxUsers)
}
// ========== 常量类型推断 ==========
fmt.Println("\n=== 常量类型推断 ===")
const inferredInt = 123
const inferredFloat = 123.456
const inferredComplex = 1 + 2i
fmt.Printf("inferredInt: %d (type: %T)\n", inferredInt, inferredInt)
fmt.Printf("inferredFloat: %f (type: %T)\n", inferredFloat, inferredFloat)
fmt.Printf("inferredComplex: %v (type: %T)\n", inferredComplex, inferredComplex)
}
输出结果:
Go
=== 基本常量 ===
Pi = 3.14159
Application: MyGoApp
Max retry times: 3
=== 类型化常量 ===
Max users: 1000 (type: int)
Greeting: Hello, 世界! (type: string)
Price: 99.99 (type: float64)
=== 常量表达式 ===
Seconds in a day: 86400
=== iota枚举 ===
Wednesday is day 3 of the week
=== 文件大小常量 ===
1GB = 1073741824 bytes
=== 大整数处理 ===
Big number (uint64): 9223372036854775807
Huge number: 9876543210123456789
Small number: 987654321
=== 常量运算 ===
Area of circle with radius 5.0: 78.54
100°C is 212.0°F
=== 常量与变量比较 ===
User count (850) is below maximum (1000)
=== 常量类型推断 ===
inferredInt: 123 (type: int)
inferredFloat: 123.456000 (type: float64)
inferredComplex: (1+2i) (type: complex128)
常量与变量区别
-
常量必须在编译时确定值,变量可以在运行时确定
-
常量不能修改,变量可以
-
常量可以是无类型的
常量使用场景
-
配置值(如端口号、超时时间)
-
枚举值
-
数学常数
-
程序中固定不变的值
注意事项
-
常量不能使用
:=
语法声明 -
常量所有算术、逻辑和比较运算结果也是常量
-
常量不能使用函数调用初始化(除了内置函数如
len
)