掌握Go语言中的映射、常量与指针

映射(Maps)

Go语言中的映射(map)等同于其他编程语言中的哈希表。映射的最大优势是可以使用任何可比较的数据类型作为键,也就是所谓的"map key"或"键"。尽管Go语言中的映射并没有限制哪些数据类型可以作为键,但键必须是可比较的,即Go编译器必须能够区分不同的键,也就是说,键必须支持==操作符。

几乎所有的数据类型都是可比较的,但使用bool类型作为键可能会限制映射的使用场景,而使用浮点数作为键可能会由于机器和操作系统的精度差异带来一些问题。

你可以使用make()函数创建一个键为字符串,值为整数的空映射:

go 复制代码
iMap = make(map[string]int)

或者使用字面量直接创建并初始化一个映射:

go 复制代码
anotherMap := map[string]int{
    "k1": 12,
    "k2": 13,
}

映射是对哈希表的引用,Go隐藏了哈希表的具体实现,因此你无需担心其复杂性。你可以像访问数组或切片一样,使用键访问映射中的元素:

go 复制代码
fmt.Println(anotherMap["k1"])

可以使用delete()函数删除映射中的键值对:

go 复制代码
delete(anotherMap, "k1")

遍历映射

你可以使用range关键字遍历映射的所有元素:

go 复制代码
for key, value := range iMap {
    fmt.Println(key, value)
}

这是一个简单的示例:

go 复制代码
package main
import "fmt"

func main() {
    iMap := make(map[string]int)
    iMap["k1"] = 12
    iMap["k2"] = 13
    fmt.Println("iMap:", iMap)

    anotherMap := map[string]int{
        "k1": 12,
        "k2": 13,
    }
    fmt.Println("anotherMap:", anotherMap)

    delete(anotherMap, "k1")
    fmt.Println("anotherMap:", anotherMap)

    _, ok := iMap["doesItExist"]
    if ok {
        fmt.Println("存在!")
    } else {
        fmt.Println("不存在")
    }

    for key, value := range iMap {
        fmt.Println(key, value)
    }
}

运行上述代码的输出结果如下:

bash 复制代码
iMap: map[k1:12 k2:13]
anotherMap: map[k1:12 k2:13]
anotherMap: map[k2:13]
不存在
k1 12
k2 13

值得注意的是,调用delete()函数多次不会有任何影响,且不会产生警告。

nil映射

可以使用nil映射,但不能向其中存储数据。例如:

go 复制代码
aMap := map[string]int{}
aMap["test"] = 1

这个代码是合法的。然而,如果你试图向一个nil映射中插入数据,程序会报错:

go 复制代码
aMap := map[string]int{}
aMap = nil
aMap["test"] = 1

这会导致运行时错误:panic: assignment to entry in nil map

常量(Constants)

Go语言支持常量,常量的值在程序运行期间是不能改变的。常量使用const关键字来定义。使用常量的主要好处是可以确保它们的值在程序执行期间不会发生变化,且这些值是在编译时确定的。

例如,可以这样定义常量:

go 复制代码
const HEIGHT = 200

也可以通过分组的方式定义多个相关的常量:

go 复制代码
const (
    C1 = "常量1"
    C2 = "常量2"
    C3 = "常量3"
)

如果你定义了数值型常量,可以在表达式中灵活使用,例如:

go 复制代码
const value = 123
const s1 = value * 10

iota常量生成器

iota是Go语言中的常量生成器,常用于声明一系列相关的递增值,无需显式地为每个常量赋值。来看一个例子:

go 复制代码
const (
    Zero = iota  // 0
    One          // 1
    Two          // 2
    Three        // 3
)

也可以在位运算表达式中使用iota

go 复制代码
const (
    p2_0 = 1 << iota  // 1 << 0 = 1
    p2_2 = 1 << iota  // 1 << 2 = 4
    p2_4 = 1 << iota  // 1 << 4 = 16
)

运行后的结果如下:

bash 复制代码
2^0: 1
2^2: 4
2^4: 16

iota的自动递增功能可以在需要生成一系列常量时极大简化代码。

指针(Pointers)

Go语言中支持指针,指针是存储变量内存地址的变量。指针允许你共享数据,尤其是在函数之间传递数据时。你可以通过*来获取指针指向的值,使用&获取变量的内存地址。

例如,定义一个接受指针作为参数的函数:

go 复制代码
func getPointer(n *int) {
    *n = *n * *n
}

指针可以让你在函数内部修改传入的变量,而无需返回任何值:

go 复制代码
package main
import "fmt"

func getPointer(n *int) {
    *n = *n * *n
}

func main() {
    i := 10
    getPointer(&i)
    fmt.Println("i:", i)  // 输出:i: 100
}

指针虽然功能强大,但使用不当容易引发难以调试的错误,因此在使用时需要格外小心。

总结

Go语言的映射和常量提供了强大的数据处理能力,映射可以存储多种不同类型的数据,并支持动态操作,而常量则确保了程序中的一些值在编译期间不会发生改变。此外,Go语言中的指针允许数据共享,尤其是在处理复杂数据结构时极具优势。通过本文的介绍,读者可以更好地理解和应用这些Go语言中的重要特性。

相关推荐
Dovis(誓平步青云)2 小时前
《QT学习第四篇:常见事件与UDP、TCP、文件系统、(锁、信号量、条件变量》
c语言·开发语言·汇编·qt
for_ever_love__8 小时前
UI学习:UISearchController基础了解和应用
学习·ui·ios·objective-c
isyangli_blog10 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb20081110 小时前
FastAPI APIRouter
开发语言·python
Benszen10 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆10 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木10 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
喵个咪10 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
杨充11 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
噜噜噜阿鲁~11 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言