Go语言教程-变量、常量、命名规则

命名规则

Go语言的命名规则遵循以下规范:

  1. 字母或下划线开头:名称必须以字母或下划线开头

  2. 后续字符:可以是字母、数字或下划线

  3. 区分大小写Namename是不同的标识符

  4. 关键字不能作为标识符 :如func, var, package

  5. 推荐使用驼峰命名法

    • 导出名称(首字母大写):UserName

    • 非导出名称(首字母小写):userName

变量

变量声明

Go 复制代码
// 单变量声明
var name string = "John"

// 类型推断
var age = 30

// 多变量声明
var width, height int = 100, 50

// 简短声明(只能在函数内使用)
count := 10

变量默认值

  • 数值类型:0

  • 布尔类型:false

  • 字符串:""(空字符串)

  • 指针、函数、接口、slice、channel、map:nil

全局变量

全局变量是在函数外部声明的变量,可以在整个包内访问(如果首字母大写,则可以在其他包中访问)。

全局变量特点

  1. 声明在函数体外部

  2. 生命周期贯穿整个程序运行期间

  3. 如果首字母大写,可以被其他包访问

  4. 如果首字母小写,只能在当前包内访问

全局变量示例

Go 复制代码
package main  // 必须声明包名(main包才能直接运行)

import "fmt"  // 需要导入fmt包才能使用Println

var global = "我是全局的" // 全局变量

func main() {
    fmt.Println(global) // 可以访问
}

局部变量

局部变量是在函数或代码块内部声明的变量,只在声明它们的函数或代码块内有效。

局部变量特点

  1. 声明在函数或代码块内部

  2. 生命周期仅限于函数或代码块执行期间

  3. 只能在声明它们的函数或代码块内访问

  4. 可以使用简短声明语法 :=

局部变量示例

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)

常量与变量区别

  1. 常量必须在编译时确定值,变量可以在运行时确定

  2. 常量不能修改,变量可以

  3. 常量可以是无类型的

常量使用场景

  1. 配置值(如端口号、超时时间)

  2. 枚举值

  3. 数学常数

  4. 程序中固定不变的值

注意事项

  1. 常量不能使用:=语法声明

  2. 常量所有算术、逻辑和比较运算结果也是常量

  3. 常量不能使用函数调用初始化(除了内置函数如len