第 4 章 - Go 语言变量与常量

1. 变量声明

在Go语言中,变量声明有多种方式。常见的变量声明方式包括使用 var 关键字、短变量声明和类型推断。

1.1 使用 var 关键字声明变量

这是最传统的方式,适用于显式声明变量的类型。

go 复制代码
package main

import "fmt"

func main() {
    var a int = 10
    var b string = "Hello, Go!"

    fmt.Println("a:", a)
    fmt.Println("b:", b)
}
1.2 短变量声明

短变量声明使用 := 操作符,适用于在函数内部声明变量。编译器会根据赋值表达式的类型自动推断变量的类型。

go 复制代码
package main

import "fmt"

func main() {
    a := 10
    b := "Hello, Go!"

    fmt.Println("a:", a)
    fmt.Println("b:", b)
}
1.3 类型推断

Go语言支持类型推断,即编译器可以根据初始值自动推断变量的类型。这在使用 var 关键字声明变量时也可以实现。

go 复制代码
package main

import "fmt"

func main() {
    var a = 10
    var b = "Hello, Go!"

    fmt.Println("a:", a)
    fmt.Println("b:", b)
}

2. 常量定义

常量在Go语言中使用 const 关键字声明。常量的值在编译时确定,不能在运行时修改。

2.1 声明单个常量
go 复制代码
package main

import "fmt"

func main() {
    const pi float64 = 3.14159
    const greeting = "Hello, World!"

    fmt.Println("pi:", pi)
    fmt.Println("greeting:", greeting)
}
2.2 声明多个常量

可以一次性声明多个常量,使用逗号分隔。

go 复制代码
package main

import "fmt"

func main() {
    const (
        pi      = 3.14159
        e       = 2.71828
        phi     = 1.61803
        gravity = 9.8
    )

    fmt.Println("pi:", pi)
    fmt.Println("e:", e)
    fmt.Println("phi:", phi)
    fmt.Println("gravity:", gravity)
}

3. 类型推断

类型推断是Go语言的一个重要特性,它使得代码更加简洁。编译器会根据初始值自动推断变量的类型。

3.1 简单类型推断
go 复制代码
package main

import "fmt"

func main() {
    a := 10           // int
    b := "Hello, Go!" // string
    c := 3.14         // float64

    fmt.Println("a:", a)
    fmt.Println("b:", b)
    fmt.Println("c:", c)
}
3.2 复合类型推断

Go语言支持复杂的类型推断,例如数组、切片、映射等。

go 复制代码
package main

import "fmt"

func main() {
    arr := [3]int{1, 2, 3}        // 数组
    slice := []int{1, 2, 3, 4, 5} // 切片
    map_ := map[string]int{"a": 1, "b": 2} // 映射

    fmt.Println("Array:", arr)
    fmt.Println("Slice:", slice)
    fmt.Println("Map:", map_)
}

4. 综合示例

下面是一个综合示例,展示了变量声明、常量定义和类型推断的多种用法。

go 复制代码
package main

import "fmt"

func main() {
    // 使用 var 关键字声明变量
    var age int = 30
    var name string = "Alice"

    // 短变量声明
    height := 1.75
    city := "New York"

    // 常量定义
    const pi float64 = 3.14159
    const greeting = "Hello, World!"

    // 复合类型推断
    arr := [3]int{1, 2, 3}
    slice := []int{1, 2, 3, 4, 5}
    map_ := map[string]int{"a": 1, "b": 2}

    // 打印所有变量和常量
    fmt.Println("age:", age)
    fmt.Println("name:", name)
    fmt.Println("height:", height)
    fmt.Println("city:", city)
    fmt.Println("pi:", pi)
    fmt.Println("greeting:", greeting)
    fmt.Println("Array:", arr)
    fmt.Println("Slice:", slice)
    fmt.Println("Map:", map_)
}

5. 总结

通过上述示例,我们详细讲解了Go语言中的变量声明、常量定义和类型推断。这些基本概念是编写Go程序的基础,希望这些内容能帮助你更好地理解和使用Go语言。

当然,我们可以继续深入探讨更多关于变量和常量的高级用法,包括变量的作用域、多变量声明、常量的枚举和 iota 的使用等。下面是一些更详细的示例和解释。

6. 变量的作用域

变量的作用域决定了变量在代码中的可见性和生命周期。Go语言中有几种不同的作用域:

  • 全局变量:在所有函数之外声明的变量,可以在整个包中访问。
  • 局部变量:在函数内部声明的变量,只能在该函数内访问。
  • 块作用域 :在 {} 块内声明的变量,只能在该块内访问。
全局变量
go 复制代码
package main

import "fmt"

// 全局变量
var globalVar int = 100

func main() {
    fmt.Println("Global variable:", globalVar)
}
局部变量
go 复制代码
package main

import "fmt"

func main() {
    // 局部变量
    localVar := 200
    fmt.Println("Local variable:", localVar)
}
块作用域
go 复制代码
package main

import "fmt"

func main() {
    if true {
        blockVar := 300
        fmt.Println("Block variable inside if block:", blockVar)
    }

    // 下面的代码会报错,因为 blockVar 在 if 块外不可见
    // fmt.Println("Block variable outside if block:", blockVar)
}

7. 多变量声明

Go语言允许一次声明多个变量,可以使用 var 关键字或短变量声明。

使用 var 关键字声明多个变量
go 复制代码
package main

import "fmt"

func main() {
    var a, b, c int = 1, 2, 3
    var x, y string = "Hello", "World"

    fmt.Println("a:", a, "b:", b, "c:", c)
    fmt.Println("x:", x, "y:", y)
}
使用短变量声明声明多个变量
go 复制代码
package main

import "fmt"

func main() {
    a, b, c := 1, 2, 3
    x, y := "Hello", "World"

    fmt.Println("a:", a, "b:", b, "c:", c)
    fmt.Println("x:", x, "y:", y)
}

8. 常量的枚举和 iota

Go语言中的 iota 是一个特殊的常量生成器,可以用于生成一系列相关的常量值。iota 在每个 const 块中从0开始递增。

枚举常量
go 复制代码
package main

import "fmt"

func main() {
    const (
        Sunday = iota
        Monday
        Tuesday
        Wednesday
        Thursday
        Friday
        Saturday
    )

    fmt.Println("Sunday:", Sunday)
    fmt.Println("Monday:", Monday)
    fmt.Println("Tuesday:", Tuesday)
    fmt.Println("Wednesday:", Wednesday)
    fmt.Println("Thursday:", Thursday)
    fmt.Println("Friday:", Friday)
    fmt.Println("Saturday:", Saturday)
}
使用 iota 生成二进制标志
go 复制代码
package main

import "fmt"

func main() {
    const (
        Read  = 1 << iota // 1
        Write                // 2
        Execute              // 4
        All = Read | Write | Execute // 7
    )

    fmt.Println("Read:", Read)
    fmt.Println("Write:", Write)
    fmt.Println("Execute:", Execute)
    fmt.Println("All:", All)
}

9. 综合示例

下面是一个综合示例,展示了变量的作用域、多变量声明和常量的枚举及 iota 的使用。

go 复制代码
package main

import "fmt"

// 全局变量
var globalVar int = 100

func main() {
    // 局部变量
    localVar := 200
    fmt.Println("Global variable:", globalVar)
    fmt.Println("Local variable:", localVar)

    // 块作用域
    if true {
        blockVar := 300
        fmt.Println("Block variable inside if block:", blockVar)
    }

    // 多变量声明
    var a, b, c int = 1, 2, 3
    var x, y string = "Hello", "World"
    fmt.Println("a:", a, "b:", b, "c:", c)
    fmt.Println("x:", x, "y:", y)

    // 使用短变量声明
    d, e, f := 4, 5, 6
    z, w := "Hi", "There"
    fmt.Println("d:", d, "e:", e, "f:", f)
    fmt.Println("z:", z, "w:", w)

    // 常量的枚举和 iota
    const (
        Sunday = iota
        Monday
        Tuesday
        Wednesday
        Thursday
        Friday
        Saturday
    )

    fmt.Println("Sunday:", Sunday)
    fmt.Println("Monday:", Monday)
    fmt.Println("Tuesday:", Tuesday)
    fmt.Println("Wednesday:", Wednesday)
    fmt.Println("Thursday:", Thursday)
    fmt.Println("Friday:", Friday)
    fmt.Println("Saturday:", Saturday)

    const (
        Read  = 1 << iota // 1
        Write                // 2
        Execute              // 4
        All = Read | Write | Execute // 7
    )

    fmt.Println("Read:", Read)
    fmt.Println("Write:", Write)
    fmt.Println("Execute:", Execute)
    fmt.Println("All:", All)
}

10. 总结

通过上述示例,我们详细讲解了Go语言中的变量作用域、多变量声明、常量的枚举和 iota 的使用。这些高级用法可以帮助你编写更加简洁和高效的Go代码。希望这些内容能帮助你更好地理解和使用Go语言。

11. 变量的初始化

在Go语言中,变量可以在声明时初始化,也可以在声明后初始化。未初始化的变量会被赋予其类型的零值。

11.1 声明时初始化
go 复制代码
package main

import "fmt"

func main() {
    var a int = 10
    var b string = "Hello, Go!"

    fmt.Println("a:", a)
    fmt.Println("b:", b)
}
11.2 声明后初始化
go 复制代码
package main

import "fmt"

func main() {
    var a int
    var b string

    a = 10
    b = "Hello, Go!"

    fmt.Println("a:", a)
    fmt.Println("b:", b)
}

12. 零值

在Go语言中,未初始化的变量会被赋予其类型的零值。不同类型的零值如下:

  • int, uint, int8, int16, int32, int64, uint8, uint16, uint32, uint64: 0
  • float32, float64: 0.0
  • bool: false
  • string: ""
  • 指针、函数、接口、切片、通道、映射: nil
示例
go 复制代码
package main

import "fmt"

func main() {
    var a int
    var b float64
    var c bool
    var d string
    var e *int
    var f []int
    var g map[string]int
    var h chan int

    fmt.Println("a:", a) // 0
    fmt.Println("b:", b) // 0.0
    fmt.Println("c:", c) // false
    fmt.Println("d:", d) // ""
    fmt.Println("e:", e) // nil
    fmt.Println("f:", f) // nil
    fmt.Println("g:", g) // nil
    fmt.Println("h:", h) // nil
}

13. 常量表达式

常量表达式是在编译时计算的,可以包含常量、字面量和某些内置函数(如 lencaprealimagcomplexunsafe.Sizeof 等)。

示例
go 复制代码
package main

import "fmt"

func main() {
    const (
        a = 10
        b = a + 5
        c = len("Hello, Go!")
        d = unsafe.Sizeof(a) // 需要导入 "unsafe" 包
    )

    fmt.Println("a:", a)
    fmt.Println("b:", b)
    fmt.Println("c:", c)
    fmt.Println("d:", d)
}

14. 最佳实践

14.1 使用短变量声明

在函数内部,尽量使用短变量声明 :=,使代码更加简洁。

go 复制代码
package main

import "fmt"

func main() {
    a := 10
    b := "Hello, Go!"

    fmt.Println("a:", a)
    fmt.Println("b:", b)
}
14.2 避免全局变量

尽量避免使用全局变量,因为它们会增加代码的耦合度和复杂性。尽量将变量的作用域限制在需要的地方。

go 复制代码
package main

import "fmt"

func main() {
    // 局部变量
    localVar := 200
    fmt.Println("Local variable:", localVar)
}
14.3 使用常量代替魔法数

使用常量代替代码中的"魔法数"(没有明确含义的数字),可以使代码更具可读性和可维护性。

go 复制代码
package main

import "fmt"

const (
    MaxUsers = 100
    MinAge   = 18
)

func main() {
    users := 95
    age := 20

    if users < MaxUsers && age >= MinAge {
        fmt.Println("User can join the system.")
    } else {
        fmt.Println("User cannot join the system.")
    }
}

15. 综合示例

下面是一个综合示例,展示了变量的初始化、零值、常量表达式和一些最佳实践。

go 复制代码
package main

import (
    "fmt"
    "unsafe"
)

// 全局变量
var globalVar int = 100

func main() {
    // 局部变量
    localVar := 200
    fmt.Println("Global variable:", globalVar)
    fmt.Println("Local variable:", localVar)

    // 零值
    var a int
    var b float64
    var c bool
    var d string
    var e *int
    var f []int
    var g map[string]int
    var h chan int

    fmt.Println("a:", a) // 0
    fmt.Println("b:", b) // 0.0
    fmt.Println("c:", c) // false
    fmt.Println("d:", d) // ""
    fmt.Println("e:", e) // nil
    fmt.Println("f:", f) // nil
    fmt.Println("g:", g) // nil
    fmt.Println("h:", h) // nil

    // 常量表达式
    const (
        aConst = 10
        bConst = aConst + 5
        cConst = len("Hello, Go!")
        dConst = unsafe.Sizeof(aConst)
    )

    fmt.Println("aConst:", aConst)
    fmt.Println("bConst:", bConst)
    fmt.Println("cConst:", cConst)
    fmt.Println("dConst:", dConst)

    // 最佳实践
    users := 95
    age := 20

    const (
        MaxUsers = 100
        MinAge   = 18
    )

    if users < MaxUsers && age >= MinAge {
        fmt.Println("User can join the system.")
    } else {
        fmt.Println("User cannot join the system.")
    }
}

16. 总结

通过上述示例,我们详细讲解了Go语言中的变量初始化、零值、常量表达式以及一些最佳实践。这些知识点有助于你编写更加清晰、高效和可维护的Go代码。希望这些内容能帮助你更好地理解和使用Go语言。如果你有任何问题或需要进一步的解释,请随时提问!

相关推荐
半盏茶香4 分钟前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Evand J1 小时前
LOS/NLOS环境建模与三维TOA定位,MATLAB仿真程序,可自定义锚点数量和轨迹点长度
开发语言·matlab
LucianaiB1 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
️南城丶北离1 小时前
[数据结构]图——C++描述
数据结构··最小生成树·最短路径·aov网络·aoe网络
一个处女座的程序猿O(∩_∩)O1 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
Ronin3051 小时前
11.vector的介绍及模拟实现
开发语言·c++
✿ ༺ ོIT技术༻1 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
计算机学长大白2 小时前
C中设计不允许继承的类的实现方法是什么?
c语言·开发语言
suweijie7682 小时前
SpringCloudAlibaba | Sentinel从基础到进阶
java·大数据·sentinel
公贵买其鹿3 小时前
List深拷贝后,数据还是被串改
java