golang map中结构体元素是无法取地址的_爱思考的实践者的博客-程序员宝宝

技术标签: go  map  

map中的结构体元素是无法取地址的,即:map[string]struct类型,取&map["tmp"]是错误的。会提示报错:

   cannot assign to struct field elem["count"].count in map。

原因为:map中的元素并不是一个变量,而是一个值。因此,我们不能对map的元素进行取址操作。

1.使用示例一:map对应的值为结构体类型的值

package main

import (
	"fmt"
	"time"
)

// Counter 代表计数器的类型。
type Counter struct {
	count int
}

var mapChan = make(chan map[string]Counter, 1)

func main() {
	syncChan := make(chan struct{}, 2)

	go func() { // 接收操作
		for {
			if elem, ok := <-mapChan; ok {
				counter := elem["count"] //传值
				counter.count++
				fmt.Printf("[receiver] The elem is: %v. Elem address: %p \n", elem, &elem)
				fmt.Printf("[receiver] The counter: %d.\n", counter.count)

				/*
				map中的结构体元素是无法取地址的,即:map[string]struct类型,取&map["tmp"]是错误的.
   				使用下面的语句,会报提示语 cannot assign to struct field elem["count"].count in map.
				 */
				//elem["count"].count++
				//fmt.Printf("[receiver] The elem is: %v. Elem address: %p \n", elem, &elem)
				//fmt.Printf("[receiver] The counter: %d.\n", elem["count"].count)
			} else {
				break
			}
		}
		fmt.Println("[receiver] Stopped.")
		syncChan <- struct{}{} // 发送同步通知
	}()

	go func() { // 发送操作
		countMap := map[string]Counter{
			"count": Counter{},
		}
		for i := 0; i < 5; i++ {
			mapChan <- countMap
			time.Sleep(time.Millisecond)
			fmt.Printf("[sender] The count map: %v. Count map address: %p \n", countMap, &countMap)
			fmt.Printf("[sender] The counter: %d.\n", countMap["count"].count)
		}
		close(mapChan)
		syncChan <- struct{}{} // 发送同步通知
	}()

	<-syncChan //接收同步通知
	<-syncChan //接收同步通知
}

运行结果如下所示:

[receiver] The elem is: map[count:{0}]. Elem address: 0xc000078000
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] The elem is: map[count:{0}]. Elem address: 0xc000078010
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] The elem is: map[count:{0}]. Elem address: 0xc0000a0000
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] The elem is: map[count:{0}]. Elem address: 0xc00000c040
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] The elem is: map[count:{0}]. Elem address: 0xc000078020
[receiver] The counter: 1.
[sender] The count map: map[count:{0}]. Count map address: 0xc00000c030
[sender] The counter: 0.
[receiver] Stopped.

2. 使用示例二:map对应的值为结构体类型的指针

package main

import (
	"fmt"
	"time"
)

// Counter 代表计数器的类型。
type Counter struct {
	count int
}


// 注意:map对应的值为地址(指针)
var mapChan = make(chan map[string]*Counter, 1)

func main() {
	syncChan := make(chan struct{}, 2)

	go func() { // 接收操作
		for {
			if elem, ok := <-mapChan; ok {
				counter := elem["count"] //传地址
				counter.count++
				fmt.Printf("[receiver] The elem is: %v.  Elem address: %p\n", elem, &elem)
				fmt.Printf("[receiver] The counter: %d.\n", counter.count)

				/*
				map中的元素是无法取地址的,即:map[string]struct类型,取&map["tmp"]是错误的.
   				使用下面的语句,会报提示语 cannot assign to struct field elem["count"].count in map.
				 */
				//elem["count"].count++
				//fmt.Printf("[receiver] The elem is: %v. Elem address: %p \n", elem, &elem)
				//fmt.Printf("[receiver] The counter: %d.\n", elem["count"].count)
			} else {
				break
			}
		}
		fmt.Println("[receiver] Stopped.")
		syncChan <- struct{}{}
	}()

	go func() { // 发送操作
		countMap := map[string]*Counter{
			"count": &Counter{},
		}
		for i := 0; i < 5; i++ {
			mapChan <- countMap
			time.Sleep(time.Millisecond)
			fmt.Printf("[sender] The count map: %v. Count map address: %p \n", countMap, &countMap)
			fmt.Printf("[sender] The counter: %d.\n", countMap["count"].count)
		}
		close(mapChan)
		syncChan <- struct{}{}
	}()

	<-syncChan
	<-syncChan
}

运行结果如下所示:

[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00008a000
[receiver] The counter: 1.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 1.
[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00008a010
[receiver] The counter: 2.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 2.
[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00000c010
[receiver] The counter: 3.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 3.
[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00000c018
[receiver] The counter: 4.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 4.
[receiver] The elem is: map[count:0xc000074008].  Elem address: 0xc00000c020
[receiver] The counter: 5.
[sender] The count map: map[count:0xc000074008]. Count map address: 0xc000082020
[sender] The counter: 5.
[receiver] Stopped.

3. 使用示例三:map对应的值为int类型

package main

import (
	"fmt"
	"time"
)

var mapChan = make(chan map[string]int, 1)

func main() {
	syncChan := make(chan struct{}, 2)

	go func() { // 接收操作
		for {
			if elem, ok := <-mapChan; ok { // 从通道中获取值
				elem["count"]++
				fmt.Printf("[receiver] The elem is: %v. Elem address is: %p \n", elem, &elem)
			} else {
				break
			}
		}
		fmt.Println("[receiver] Stopped.")
		syncChan <- struct{}{} // 发送同步通知
	}()

	go func() { // 发送操作
		countMap := make(map[string]int) // map为引用类型,发送和接收的元素为同一个值
		for i := 0; i < 5; i++ {
			countMap["count"]++
			mapChan <- countMap // 向通道中输入值
			time.Sleep(time.Millisecond)
			fmt.Printf("[sender] The count map: %v. Count map address: %p \n", countMap, &countMap)
		}
		close(mapChan) // 关闭通道
		syncChan <- struct{}{} // 发送同步通知
	}()


	<-syncChan //接收同步通知
	<-syncChan //接收同步通知
	fmt.Println(" map为引用类型,发送和接收的元素指向同一个值.")
}

运行结果如下所示:

[receiver] The elem is: map[count:2]. Elem address is: 0xc000078000
[sender] The count map: map[count:2]. Count map address: 0xc00000c030
[receiver] The elem is: map[count:4]. Elem address is: 0xc000078010
[sender] The count map: map[count:4]. Count map address: 0xc00000c030
[receiver] The elem is: map[count:6]. Elem address is: 0xc00000c040
[sender] The count map: map[count:6]. Count map address: 0xc00000c030
[receiver] The elem is: map[count:8]. Elem address is: 0xc0000a4000
[sender] The count map: map[count:8]. Count map address: 0xc00000c030
[receiver] The elem is: map[count:10]. Elem address is: 0xc000078020
[sender] The count map: map[count:10]. Count map address: 0xc00000c030
[receiver] Stopped.
 map为引用类型,发送和接收的元素指向同一个值.

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chinawangfei/article/details/86504951

智能推荐

ZED双目相机安装包_最幸伏的人的博客-程序员宝宝

最近在做双目相机的项目,发现这个ZED官网特别卡,下载特别费劲,这里给一个安装包SDK,CUDA10.2–X64版本。有需要的可以下载。百度网盘分享:链接:https://pan.baidu.com/s/1EEglb9f6VyqqHiiW6o1fxA提取码:u6f7...

腾讯首发汽车解决方案 助力广汽打造新智能网联云平台_weixin_33695450的博客-程序员宝宝

5月24日腾讯云+未来峰会汽车专场在广州举行。腾讯云联合腾讯车联、腾讯科恩实验室发布汽车行业解决方案,通过云计算、AI、大数据、内容生态、安全能力等优势技术,助力车企数字化升级转型。中国车企龙头广汽、长安、上汽、一汽、北汽,以及国际车企菲克的相关负责人出席并做分享。同时,会上腾讯云与广汽研究院达成\"智能网联云平台合作开发协议\"。\\\\腾讯副总裁、腾讯云总裁邱跃鹏(左), 广汽研究院院长王秋景...

关于ajax中出现2次请求的原因及解决办法_恪守你我他的博客-程序员宝宝_ajax为什么会请求两次

前言在项目中发现ajax中出现两次请求,OPTIONS请求和POST请求,由于在上传数据的时候,后台可能2次都有反应,因此会造成数据上的错误。1,具体表现如下:查找原因是浏览器对简单跨域请求和复杂跨域请求的处理区别。2,原因如下: 浏览器对复杂跨域请求的处理,在发送真正的请求前, 会先发送一个方法为OPTIONS的预请求(preflight request), 用于试探服务端...

vue.js 重学笔记(7) --如何获取事件对象_前端一号站的博客-程序员宝宝_获取事件对象

引入&gt; vue pk javascript:&gt; 问题:在页面中有一个按钮,当点击按钮的时候,控制台会输出“hello word”javascript实现流程获取按钮对象给按钮实例绑定点击事件代码展示html代码&lt;button id="btn" type="button"&gt;按我&lt;/button&gt;script代码var obtn=document.getElementById("btn2"); -- obtn.onclick=function

HCIP IOT第二天_k-len的博客-程序员宝宝

判断题1 Huawei LiteOS不支持在NB-IOT芯片上运行 ×(错误)2 产品模型是用来描述设施能力的文件,通过JSON的格式定义了设备的基本属性、上报数据和下发命令的消息格式。 √(正确)3 华为云解决方案中的智慧电梯,能够实时监测电梯运行维保数据,实现电梯维保智能化监管,结合大数据技术、绘制故障电梯模型,及时精准维保,减少事故发生几率。 √(正确)4 软件定时器,是基于系统Tick时钟中断且由硬件来模拟的定时器 ×(错误)5 Huawe.

LeetCode刷题笔记 图 拓扑排序_王清欢Randy的博客-程序员宝宝

拓扑排序简介​ 拓扑排序(topological sort)是一种常见的,对有向无环图排序的算法。给定有向无环图中的 N 个节点,我们把它们排序成一个线性序列;若原图中节点 i 指向节点 j,则排序结果中 i 一定在 j 之前。拓扑排序的结果不是唯一的,只要满足以上条件即可。210 课程表 II给定 N 个课程和这些课程的前置必修课,求可以一次性上完所有课的顺序输入是一个正整数,表示课程数量,和一个二维矩阵,表示所有的有向边,例如 [1,0] 表示上课程 1 之前必须先上课程 0。输出是一个一维数组

随便推点

IBM预测五大创新技术 智能电网5年内实现_ciyi7513的博客-程序员宝宝

IBM近日发布《未来5年的5大创新(NextFiveinFive)》报告书,提出五项可能改变人类的五大创新,包括“节能更容易,价格更低廉”“吃什么就像什么”“手机不再只是手机”“医生将拥有超强感知能力,提供更精准的诊断与医疗服务...

java视图层_Java课程设计---新建视图层_weixin_39996798的博客-程序员宝宝

1、创建登录窗口登录窗口类:LoginView.javapackage com.system.view;import java.awt.BorderLayout;import java.awt.EventQueue;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.border.EmptyBorder;/*...

知名公司的Java面试题_架构师成长营的博客-程序员宝宝

查看不同公司新鲜真实的Java面试题,摘自Glassdoor.com巴克莱投资:假设有一个 getNextparson() 方法返回 Person 对象,Person 类实现了 comparable 接口,现在从文件中读取记录并排序,然后给出前 1000 条记录,纸上作答 答案见Glassdoor 写一个函数,传入 2 个有序的整数数组,返回一个有序的整数数组。 答案见Glassdo...

Codeforces Round #401 (Div. 2) D. Cloud of Hashtags 贪心、字符串处理_ProLightsfxjh的博客-程序员宝宝

题意:给出n个字符串,要求删除尽可能短的后缀,是这n个字符串的字典序是非递减的。 贪心、字符串处理可知,可以且需要从倒数第二个字符串开始考虑删除后缀,使s[i] <= s[i+1],因为只能从后往前处理,然后删除后缀的时候满足删除尽可能短的后缀即可。复杂度 O(n*length)

vue.js隐藏滚动条的方法_极星(*^_^*)的博客-程序员宝宝

vue.js去掉滚动条的方法:1、设置滚动条:overflow-x: scroll; white-space: nowrap;2、隐藏滚动条:::-webkit-scrollbar { width: 0 !important;}::-webkit-scrollbar { width: 0 !important;height: 0;}

一篇文章入门Redis_weixin_34309543的博客-程序员宝宝

Redis是目前最流行的NoSQL数据库,最重要的是它是运行在内存上的数据库。所以几乎所有高并发需求的产品都会考虑使用Redis作为数据库缓存。不同于MongoDB的以硬盘存储为主、内存为辅,Redis是真·内存存储,即所有数据都存在内存中,只是偶尔间歇性的保存到硬盘上备份。Redis特点:NoSQL:采用类似JSON的Key-V...

推荐文章

热门文章

相关标签