zoukankan      html  css  js  c++  java
  • go语言---map

    go语言---map

    https://blog.csdn.net/cyk2396/article/details/78890185

    一.map的用法:

    type PersonDB struct {
    	Id      string
    	Name    string
    	Address string
    }
    
    fmt.Println("=========Map===========")
    	//map是一堆键值对的未排序集合,在golang中是内置类型,可以直接使用,不像Java需要引入HashMap
    	var personMap map[string]PersonDB                                 //声明一个map变量,string是键的类型,PersonDB是值的类型
    	personMap = make(map[string]PersonDB, 10)                         //创建一个map,初始容量为10
    	personMap["1"] = PersonDB{Id: "1", Name: "zs", Address: "北京市房山区"} //给map元素赋值
    	personMap["2"] = PersonDB{Id: "2", Name: "ls", Address: "北京市海淀区"}
    	//使用内置函数delete删除personMap中key="1"的元素,如果找不到该key,则什么也不会发生,如果personMap为nil,则抛错
    	delete(personMap, "1")
    	if value, ok := personMap["2"]; ok { //找到key=2的元素,则ok=true,value为找到的值;否则ok=false
    		fmt.Println(value)
    	}
    
    	personMap2 := map[string]PersonDB{"3": PersonDB{"3", "ww", "杭州市西湖区"}} //创建并初始化一个map
    	personMap2["4"] = PersonDB{"4", "ll", "北京市东城区"}
    	for k, v := range personMap2 { //使用range遍历map中的元素
    		fmt.Println(k, v)
    		if k == "3" {
    			v.Name = "wwUpdate"
    			personMap2["3"] = v //可更改value值
    			//以下这种赋值方式会报错,只能对value赋值,不能直接更改其成员变量
    			// personMap2["3"].Name = "wwUpdate" //cannot assign to struct field personMap2["3"].Name in map
    		}
    	}
    	fmt.Println(personMap2)
    
    	
    
    

    输出结果:
    fatal error: concurrent map writes
    由结果可知:map不是线程安全的。
    至于为什么不是线程安全,以后再分析

    三.map传值还是传引用?

    运行以下代码:

    //map传值还是传引用? map和slice,channel一样,内部都有一个指向真正存储空间的指针,所以,即使传参时是对值的复制(传值),但都指向同一块存储空间。
    	var myMapV map[string]int
    	var myMap1 map[string]int
    	myMapV = map[string]int{"value": 0}
    	myMap1 = myMapV
    	fmt.Println("m =", myMapV)
    	fmt.Println("m1 =", myMap1)
    	myMap1["value"] = 1
    	fmt.Println("m =", myMapV)
    	fmt.Println("m1 =", myMap1)
    
    

    二.map是线程安全的吗?

    运行以下代码:

    
    //map不是线程安全的。
    	 cMap := make(map[string]int)
    	for i := 0; i < 100; i++ {
    		go func() {
    			for j := 0; j < 100; j++ {
     			cMap[fmt.Sprintf("%d", j)] = j //fatal error: concurrent map writes
    			}
    		}()
    	}
    	 time.Sleep(3 * time.Second)
    
    

    输出结果:
    m = map[value:0]
    m1 = map[value:0]
    m = map[value:1]
    m1 = map[value:1]
    我们发现,当修改了m1,m也随着改变了,这看似是传引用,但其实map也是传值的,它的原理和数组切片类似。map内部维护着一个指针,该指针指向真正的map存储空间。我们可以将map描述为如下结构:

    type map[key]value struct{
    impl *Map_K_V
    }
    type Map_K_V struct{
    //......
    }
    其实,map和slice,channel一样,内部都有一个指向真正存储空间的指针,所以,即使传参时是对值的复制(传值),但都指向同一块存储空间。

  • 相关阅读:
    浏览器返回按钮不会触发onLoad事件
    js常用方法
    清除浮动
    Hbuilder快捷键
    页面跳转
    castapp.js颜色配置
    mui学习
    css 特殊使用技巧
    mui框架如何实现页面间传值
    从0到千万级访问量网站架构演变史
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/9280847.html
Copyright © 2011-2022 走看看