Go之路 - 2.go的常量变量[完整版]

这里煮包总结的很系统,不懂的后面记得回来看。

一、基本变量声明

1. 标准声明方式

go 复制代码
// 单个变量声明
var name string
var age int
var isStudent bool

// 多个同类型变量
var x, y int

// 多个不同类型变量
var (
    firstName string
    lastName  string
    score     float64
    enrolled  bool
)

2. 声明并初始化

go 复制代码
// 声明时初始化
var name string = "Alice"
var age int = 25

// 类型推断(编译器自动推断类型)
var name = "Bob"      // 推断为 string
var age = 30          // 推断为 int
var salary = 50000.0  // 推断为 float64

// 多个变量同时初始化
var a, b, c = 1, 2.5, "hello"

3. 短变量声明(最常用)

go 复制代码
// 只能在函数内部使用
func main() {
    name := "Charlie"      // 声明并初始化
    age := 35             // int
    height := 1.75        // float64
    isEmployed := true    // bool
    
    // 多个变量
    x, y, z := 10, 20, "world"
    
    // 交换变量值
    a, b := 1, 2
    a, b = b, a  // a=2, b=1
}

二、零值(Zero Values)

Go 中声明但未初始化的变量会自动赋零值:

go 复制代码
var i int      // 0
var f float64  // 0.0
var b bool     // false
var s string   // ""
var p *int     // nil
var arr [3]int // [0, 0, 0]
var m map[string]int // nil
var slice []int      // nil

三、匿名变量(Blank Identifier)

1. 忽略函数返回值

go 复制代码
func getUserInfo() (string, int, error) {
    return "Alice", 30, nil
}

func main() {
    // 只关心姓名,忽略年龄和错误
    name, _, _ := getUserInfo()
    fmt.Println(name)  // Alice
    
    // 只关心错误
    _, _, err := getUserInfo()
    if err != nil {
        // 处理错误
    }
}

2. 在循环中忽略索引或值

go 复制代码
numbers := []int{1, 2, 3, 4, 5}

// 只关心值,不关心索引
for _, value := range numbers {
    fmt.Println(value)
}

// 只关心索引,不关心值
for index, _ := range numbers {
    fmt.Println(index)
}

3. 忽略导入包的副作用

go 复制代码
import (
    _ "database/sql"     // 只执行包的init函数
    "fmt"
    _ "github.com/lib/pq" // PostgreSQL驱动注册
)

四、特殊变量用法

1. 常量声明

go 复制代码
const Pi = 3.14159
const MaxSize = 1024

// 多个常量
const (
    StatusOK      = 200
    StatusCreated = 201
    Prefix        = "GO_"
)

// iota 枚举
const (
    Sunday = iota  // 0
    Monday         // 1
    Tuesday        // 2
    Wednesday      // 3
)

// iota 表达式
const (
    KB = 1 << (10 * iota)  // 1 << 0 = 1
    MB                     // 1 << 10 = 1024
    GB                     // 1 << 20 = 1048576
)

2. 变量作用域

go 复制代码
package main

var globalVar = "I'm global"  // 包级别变量

func main() {
    localVar := "I'm local"    // 函数级别变量
    
    {
        blockVar := "I'm in block"  // 块级别变量
        fmt.Println(blockVar)
    }
    // fmt.Println(blockVar)  // 错误:blockVar未定义
}

3. 指针变量

go 复制代码
func main() {
    x := 10
    var ptr *int = &x  // ptr指向x的地址
    
    fmt.Println(x)     // 10
    fmt.Println(*ptr)  // 10(解引用)
    
    *ptr = 20         // 通过指针修改变量值
    fmt.Println(x)    // 20
}

4. 类型转换变量

go 复制代码
func main() {
    var i int = 42
    var f float64 = float64(i)  // 显式类型转换
    var u uint = uint(f)
    
    // 简短写法
    f2 := float64(i)
    u2 := uint(f2)
}

五、复合类型变量

1. 数组和切片

go 复制代码
// 数组(固定长度)
var arr1 [3]int = [3]int{1, 2, 3}
arr2 := [...]int{1, 2, 3, 4}  // 编译器计算长度

// 切片(动态数组)
var slice1 []int = []int{1, 2, 3}
slice2 := make([]int, 3, 5)  // 长度3,容量5
slice3 := []string{"a", "b", "c"}

2. Map

go 复制代码
// 声明并初始化
var m1 map[string]int = map[string]int{
    "apple":  1,
    "banana": 2,
}

// 短声明
m2 := map[string]float64{
    "pi": 3.14159,
    "e":  2.71828,
}

// 使用make
m3 := make(map[int]string)
m3[1] = "one"

3. 结构体

go 复制代码
type Person struct {
    Name string
    Age  int
}

func main() {
    // 各种初始化方式
    var p1 Person
    p1.Name = "Alice"
    
    p2 := Person{"Bob", 30}  // 必须按顺序
    
    p3 := Person{
        Name: "Charlie",
        Age:  25,  // 注意末尾逗号
    }
    
    // 匿名结构体
    p4 := struct {
        Name string
        Age  int
    }{
        Name: "David",
        Age:  28,
    }
}

总结要点

  1. 短声明 (:=) 最常用,但只能在函数内使用
  2. var 声明 用于包级别变量或需要零值的变量
  3. 匿名变量 (_) 用于忽略不需要的返回值
  4. Go 有自动零值初始化,不会出现未初始化错误
  5. 变量作用域严格遵循块作用域规则
  6. 类型转换必须显式进行
  7. 复合类型(map、slice)需要初始化后才能使用

掌握这些变量用法是学习 Go 语言的基础,建议多练习不同的声明和初始化方式,理解它们各自适用的场景。

相关推荐
kkk_皮蛋2 小时前
深入理解 WebRTC 临界锁实现与 C++ RAII 机制
开发语言·c++·webrtc
i_am_a_div_日积月累_2 小时前
el-table实现自动滚动;列表自动滚动
开发语言·javascript·vue.js
闲人编程2 小时前
Flask-SQLAlchemy高级用法:关系建模与复杂查询
后端·python·flask·一对多·多对多·一对一·自引用
Li_7695322 小时前
Spring Cloud —— SkyWalking(五)
java·后端·spring·spring cloud·skywalking
武子康2 小时前
大数据-180 Elasticsearch 近实时搜索:Segment、Refresh、Flush、Translog 全流程解析
大数据·后端·elasticsearch
武子康2 小时前
Java-189 Guava Cache 源码剖析:LocalCache、Segment 与 LoadingCache 工作原理全解析
java·redis·后端·spring·缓存·guava·guava cache
weixin_307779132 小时前
Jenkins Jackson 2 API插件详解:JSON处理的基础支柱
运维·开发语言·架构·json·jenkins
踏浪无痕2 小时前
彻底搞懂微服务 TraceId 传递:ThreadLocal、TTL 与全链路日志追踪实战
后端·微服务·面试
程序员小假2 小时前
我们来说一说 Redis 主从复制的原理及作用
java·后端