map基本使用及指针问题|Go主题月

简介: map基本使用及指针问题|Go主题月

map基本使用


初始化

// 使用make赋值
map1 = make(map[string]string)
// 字面量赋值
map2 := map[string]string{}

赋值

// make方式
map1 = make(map[string]string)
map1["go"] = "go语言"
// 字面量
map2 := map[string]string{
    "go" : "go语言",
}

访问

// 获取map1里key为`go`的值
value := map1["go"]

遍历

// 使用range关键字
for k,v:=range map1{
    fmt.Printf("key:%s  ==>  value:%s\n",k,v)
}

使用map存储指针会出现的问题

当map存在指针类型的值时,可能会出现如下情况

首先看看下面的代码输出情况:

package main
import (
  "fmt"
)
func main() {
  m2:=make(map[string]*Student)
  people := []Student{
    {Name: "Zhangsan", Age: 20},
    {Name: "Lilei", Age: 23},
    {Name: "Wangmeimei", Age: 22},
  }
  for _,v:=range people{
    m2[v.Name]=&v
  }
  for k,v:=range m2{
    fmt.Printf("key:%s  ==>  Name:%s\n",k,v.Name)
  }
}
type Student struct {
  Name string
  Age int
}

输出:

key:Zhangsan  ==>  Name:Wangmeimei
key:Lilei  ==>  Name:Wangmeimei
key:Wangmeimei  ==>  Name:Wangmeimei

是不是和期望的不一样,原先期望的是把切片里的*Student全部拷贝到m2集合里,可以现在复制的都是同一个。

图解

网络异常,图片无法展示
|

这是因为这个语句中vpeople的一个拷贝的值,他会随着遍历而不断变化。而m2里存的是v的在内存中的地址,所以在遍历完后,v地址上的值就是切片的最后一个值,所以我们m2集合里存的值就统一变成了切片最后的一个值了。

for _,v:=range people{
    m2[v.Name]=&v
}

改进

解决上面的方法也比较简单,就是改一下循环语句

- for _,v:=range people{
-    m2[v.Name]=&v
- }
+ for i,v:=range people{
+   m2[v.Name]=&people[i]
+ }

这样就是直接存储原切片的地址了。

目录
相关文章
go语言中遍历映射(map)
go语言中遍历映射(map)
427 8
|
9月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
429 2
|
12月前
|
存储 人工智能 安全
深入理解 go sync.Map - 基本原理
本文介绍了 Go 语言中 `map` 在并发使用时的常见问题及其解决方案,重点对比了 `sync.Mutex`、`sync.RWMutex` 和 `sync.Map` 的性能差异及适用场景。文章指出,普通 `map` 不支持并发读写,容易引发错误;而 `sync.Map` 通过原子操作和优化设计,在某些场景下能显著提升性能。同时详细讲解了 `sync.Map` 的基本用法及其适合的应用环境,如读多写少或不同 goroutine 操作不同键的场景。
568 1
|
存储 安全 Go
Map的遍历与判断键是否存在-《Go语言实战指南》
本文介绍了 Go 语言中对 `map` 的常见操作,包括遍历所有项和判断键是否存在。通过 `for range` 可以遍历 `map` 的键值对、仅键或仅值(需忽略键)。注意,`map` 遍历顺序是随机的。判断键是否存在时,使用双赋值语法 `value, ok := map[key]`,其中 `ok` 表示键是否存在。直接访问不存在的键会返回类型的零值,可能导致逻辑错误。掌握这些机制可更安全高效地处理键值对数据。
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
|
存储 安全 Go
Go语言中的map数据结构是如何实现的?
Go 语言中的 `map` 是基于哈希表实现的键值对数据结构,支持快速查找、插入和删除操作。其原理涉及哈希函数、桶(Bucket)、动态扩容和哈希冲突处理等关键机制,平均时间复杂度为 O(1)。为了确保线程安全,Go 提供了 `sync.Map` 类型,通过分段锁实现并发访问的安全性。示例代码展示了如何使用自定义结构体和切片模拟 `map` 功能,以及如何使用 `sync.Map` 进行线程安全的操作。
592 9
go语言for遍历映射(map)
go语言for遍历映射(map)
616 12
|
存储 Go
go语言 遍历映射(map)
go语言 遍历映射(map)
474 2
|
Go 定位技术 索引
Go 语言Map(集合) | 19
Go 语言Map(集合) | 19
|
存储 Go
Go to Learn Go之指针
Go to Learn Go之指针
253 0