Go学习笔记-Variables

Go语言的变量声明有多种方式,支持类型推断,使得代码更加简洁。Go是静态类型语言,变量在编译时就确定了类型。

变量声明的基本方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import "fmt"

func main() {
    // 1. 完整的变量声明
    var name string = "Go语言"
    var age int = 10
    var isActive bool = true
    
    fmt.Println("语言:", name)
    fmt.Println("年龄:", age)
    fmt.Println("是否活跃:", isActive)
    
    // 2. 类型推断(省略类型)
    var language = "Go"  // 自动推断为string
    var version = 1.18   // 自动推断为float64
    var stable = true    // 自动推断为bool
    
    fmt.Printf("语言: %s, 版本: %.2f, 稳定: %t\n", language, version, stable)
    
    // 3. 短变量声明(最常用)
    city := "北京"
    population := 2000
    developed := true
    
    fmt.Printf("城市: %s, 人口: %d万, 发达: %t\n", city, population, developed)
}

多变量声明

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import "fmt"

func main() {
    // 1. 同类型多变量声明
    var a, b, c int = 1, 2, 3
    fmt.Println("a:", a, "b:", b, "c:", c)
    
    // 2. 不同类型多变量声明
    var name, age, salary = "张三", 25, 8000.5
    fmt.Printf("姓名: %s, 年龄: %d, 薪资: %.1f\n", name, age, salary)
    
    // 3. 短变量声明多个变量
    x, y, z := 10, 20, 30
    fmt.Println("x:", x, "y:", y, "z:", z)
    
    // 4. 分组声明
    var (
        username string = "admin"
        password string = "123456"
        port     int    = 8080
        debug    bool   = true
    )
    
    fmt.Printf("用户: %s, 密码: %s, 端口: %d, 调试: %t\n", 
        username, password, port, debug)
}

零值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import "fmt"

func main() {
    // Go语言中,声明但未初始化的变量会被赋予零值
    var str string     // 零值: ""
    var num int        // 零值: 0
    var flag bool      // 零值: false
    var ptr *int       // 零值: nil
    
    fmt.Printf("字符串零值: '%s'\n", str)
    fmt.Printf("整数零值: %d\n", num)
    fmt.Printf("布尔零值: %t\n", flag)
    fmt.Printf("指针零值: %v\n", ptr)
    
    // 数组和切片的零值
    var arr [3]int        // 零值: [0 0 0]
    var slice []int       // 零值: []
    
    fmt.Printf("数组零值: %v\n", arr)
    fmt.Printf("切片零值: %v\n", slice)
    fmt.Printf("切片是否为nil: %t\n", slice == nil)
}

常量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package main

import "fmt"

func main() {
    // 1. 基本常量声明
    const pi = 3.14159
    const name = "Go语言"
    const debug = true
    
    fmt.Println("π =", pi)
    fmt.Println("语言:", name)
    fmt.Println("调试模式:", debug)
    
    // 2. 类型化常量
    const maxSize int = 100
    const version float64 = 1.18
    
    fmt.Printf("最大尺寸: %d, 版本: %.2f\n", maxSize, version)
    
    // 3. 常量组
    const (
        StatusOK       = 200
        StatusNotFound = 404
        StatusError    = 500
    )
    
    fmt.Println("状态码:", StatusOK, StatusNotFound, StatusError)
    
    // 4. iota枚举器
    const (
        Sunday = iota    // 0
        Monday           // 1
        Tuesday          // 2
        Wednesday        // 3
        Thursday         // 4
        Friday           // 5
        Saturday         // 6
    )
    
    fmt.Println("星期日:", Sunday)
    fmt.Println("星期一:", Monday)
    fmt.Println("星期六:", Saturday)
}

变量作用域

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main

import "fmt"

// 包级别变量(全局变量)
var globalVar = "我是全局变量"

func main() {
    // 函数级别变量(局部变量)
    localVar := "我是局部变量"
    
    fmt.Println(globalVar)
    fmt.Println(localVar)
    
    // 块级作用域
    if true {
        blockVar := "我是块级变量"
        fmt.Println(blockVar)
        
        // 可以访问外层变量
        fmt.Println("在块内访问:", localVar)
    }
    
    // fmt.Println(blockVar) // 错误:blockVar在此处不可见
    
    // for循环中的变量作用域
    for i := 0; i < 3; i++ {
        loopVar := fmt.Sprintf("循环变量_%d", i)
        fmt.Println(loopVar)
    }
    
    // fmt.Println(i) // 错误:i在此处不可见
}

类型转换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main

import "fmt"

func main() {
    // Go语言不支持隐式类型转换,必须显式转换
    
    // 1. 数值类型转换
    var a int = 42
    var b float64 = float64(a)  // int转float64
    var c int = int(b)          // float64转int
    
    fmt.Printf("a: %d, b: %.2f, c: %d\n", a, b, c)
    
    // 2. 字符串和数值转换(需要导入strconv包)
    // 这里先展示基本概念,后续章节详细介绍
    
    // 3. 字符串和字节切片转换
    str := "Hello, Go!"
    bytes := []byte(str)        // 字符串转字节切片
    str2 := string(bytes)       // 字节切片转字符串
    
    fmt.Printf("原字符串: %s\n", str)
    fmt.Printf("字节切片: %v\n", bytes)
    fmt.Printf("转换回来: %s\n", str2)
    
    // 4. 类型断言(接口类型转换,后续详细介绍)
    var i interface{} = 42
    value := i.(int)  // 断言i是int类型
    fmt.Printf("断言结果: %d\n", value)
}

指针基础

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main

import "fmt"

func main() {
    // 1. 指针声明和使用
    var num int = 42
    var ptr *int = &num  // 获取num的地址
    
    fmt.Printf("num的值: %d\n", num)
    fmt.Printf("num的地址: %p\n", &num)
    fmt.Printf("ptr的值(地址): %p\n", ptr)
    fmt.Printf("ptr指向的值: %d\n", *ptr)
    
    // 2. 通过指针修改值
    *ptr = 100
    fmt.Printf("通过指针修改后,num的值: %d\n", num)
    
    // 3. 指针的零值是nil
    var nilPtr *int
    fmt.Printf("nil指针: %v\n", nilPtr)
    fmt.Printf("指针是否为nil: %t\n", nilPtr == nil)
    
    // 4. new函数创建指针
    newPtr := new(int)  // 创建一个int类型的指针,指向零值
    fmt.Printf("new创建的指针: %p\n", newPtr)
    fmt.Printf("new创建的指针指向的值: %d\n", *newPtr)
    
    *newPtr = 200
    fmt.Printf("赋值后的值: %d\n", *newPtr)
}

变量命名规范

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main

import "fmt"

// 导出变量(首字母大写)
var ExportedVar = "可以被其他包访问"

// 未导出变量(首字母小写)
var unexportedVar = "只能在当前包内访问"

func main() {
    // 1. 驼峰命名法
    var userName = "张三"
    var userAge = 25
    var isUserActive = true
    
    // 2. 缩写词保持大写
    var userID = 12345
    var httpURL = "https://golang.org"
    var xmlData = "<root></root>"
    
    // 3. 避免使用Go关键字
    // var func = "错误" // func是关键字
    var function = "正确"
    
    // 4. 有意义的变量名
    var count = 10           // 好
    var c = 10              // 不好,不够清晰
    
    var maxRetryCount = 3   // 好
    var mrc = 3            // 不好,缩写不清晰
    
    fmt.Println(userName, userAge, isUserActive)
    fmt.Println(userID, httpURL, xmlData)
    fmt.Println(function, count, maxRetryCount)
}

总结

  1. 变量声明方式
    • var name type = value - 完整声明
    • var name = value - 类型推断
    • name := value - 短变量声明(最常用)
  2. 零值:未初始化的变量有默认零值
  3. 常量:使用const关键字,支持iota枚举
  4. 作用域:包级别、函数级别、块级别
  5. 类型转换:必须显式转换,不支持隐式转换
  6. 指针:使用&获取地址,*解引用
  7. 命名规范
    • 驼峰命名法
    • 首字母大写表示导出
    • 避免使用关键字
    • 使用有意义的名称
updatedupdated2025-09-202025-09-20