使用chan的时候选择对象还是指针
使用chan的时候选择对象还是指针
今天在写代码的时候遇到一个问题,在创建一个通道的时候,不确定创建的通道是使用chan A还是chan *A。
思考了一下,觉得这个应该和函数一样是一个值传递还是参数传递的问题。然后写了个play验证了一下。
package main
import (
"fmt"
"time"
)
type B struct {
Value int
}
type A struct {
Bv B
}
func main() {
ch := make(chan *A)
b := B{1}
a := A{Bv:b}
go func(ch chan *A){
for {
select {
case a := <-ch:
a.Bv.Value = 2
}
}
}(ch)
ch <- &a
time.Sleep(2 * time.Second)
fmt.Println(a)
}
这里a.Bv.Value的值改了。 但是如果我这里的ch是make(chan A)的话,则打印出来的值为1了。
事实证明确实是这样。再去源码里面看看。
chan的结构是在src/runtime/chan.go 的hchan。我们就看chan.go里面的recv方法
func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
这个函数就是<-ch 的时候调用的。这里的c代表的就是我们使用的这个chan, ep代表的是ch传输出来的数据存储的位置。
它在从channel中获取数据的时候调用的是
recv(c, sg, ep, func() { unlock(&c.lock) }, 3)
看到这个函数里面,就可以看到使用的是typedmemmove 这个函数,这个函数就是c中的memmove。
将原先的数据,直接拷贝到目标内存中。所以这里说明channel是进行值拷贝的。
总结
基本上,chan的使用,如果是结构体的话,建议能使用指针就使用指针。
备注
本文golang代码基于go1.11.4
使用chan的时候选择对象还是指针的更多相关文章
- Golang - 指针与引用
Golang有指针 , 那么一切数据都是值传递吗 ? 都需要用户进行指针传递吗, 其实不然, 对于Go语言, 虽然有指针, 但是其也有引用传递. 是不是很绕, 因为引用传递就是指针传递哇 . 我们 ...
- golang的nil
golang中什么样的类型可以赋值nil? 类型文档中有注定"uninitialized value is nil"的类型都可以赋值nil. golang的基本类型不能赋值nil: ...
- nsq topic
与Topic相关的代码主要位于nsqd/topic.go中. 上一篇文字我们讲解了下nsq的启动流程.对nsq的整体框架有了一个大概的了解.本篇文章就是由大到小.对于topic这一部分进行详尽的讲解. ...
- Go素数筛选分析
Go素数筛选分析 1. 素数筛选介绍 学习Go语言的过程中,遇到素数筛选的问题.这是一个经典的并发编程问题,是某大佬的代码,短短几行代码就实现了素数筛选.但是自己看完原理和代码后一脸懵逼(仅此几行能实 ...
- go语言学习--指针的理解
Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,array/slice,map,chan, fu ...
- go学习 --- Chan (通道)
Golang使用Groutine和channels实现了CSP(Communicating Sequential Processes)模型,channles在goroutine的通信和同步中承担着重要 ...
- Golang 中的指针 - Pointer
http://www.cnblogs.com/jasonxuli/p/6802289.html Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int ...
- go之变量、指针、引用地址
一.值类型 定义和说明 定义:变量直接指向存在内存中的值,我们称之为值类型. 值类型的变量的值存储在栈中. 值类型 将一个变量赋值给另一个变量 被称为值拷贝 实例 package main impor ...
- Go语言基础之指针
区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针. 要搞明白Go语言中的指针需要先知道3个概念:指针地址.指针类型和指针取值. Go语言中的指针 Go语言中的函数传参都是值拷贝 ...
随机推荐
- Python web简约表白网页源码分享,时光不老,我们不散!
演示站:c.lmz8.cn打开js/4.js,复制到工具箱的js代码整理那,先解密,方便查看.工具箱:tool.lmz8.cnjs代码整理.在线解码 这个便是文字,只不过呗转码了,所以要用到解码工具. ...
- TProfiler部署文档--笔记
TProfiler是一个可以在生产环境长期使用的性能分析工具.它同时支持剖析和采样两种方式,记录方法执行的时间和次数,生成方法热点 对象创建热点 线程状态分析等数据,为查找系统性能瓶颈提供数据支持. ...
- bzoj [HNOI2008]Cards
群论第一题. 发现这题也是有颜色个数限制的,所以不能用$Polya$,只能用$Burnside$ $L={\frac{1}{|G|}}{\sum_{i=1}^{m}{D(a_{i})}}$ 先$dfs ...
- bzoj 1901 主席树+树状数组
修改+查询第k小值 单纯主席树修改会打乱所有,所以再套一个树状数组维护前缀和使得修改,查询都是log 对了,bzoj上不需要读入组数,蜜汁re.. #include<cstdio> #in ...
- 【小白学C#】谈谈C#多播委托因异常而终止的解决方案
一.前言 前几天,马三在与朋友闲聊技术的时候,朋友忽然抛出一个问题,把马三难倒了,本着求知的精神,回来以后马三就查阅了相关资料并做了一些实验,终于把问题搞明白了,因此写下本篇博客记录一下.首先,问题是 ...
- ASP.NET Core Web API 索引 (更新Identity Server 4 视频教程)
GraphQL 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上) 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下) [视频] 使用ASP.NET C ...
- 负载,性能测试工具-Gatling
前言 Gatling Gatling是一款功能强大的负载测试工具,它为易于使用,高可维护性和高性能而设计. 开箱即用,Gatling由于对HTTP协议的出色支持,使其成为负载测试任何HTTP服务器的首 ...
- Redux的中间件原理分析
redux的中间件对于使用过redux的各位都不会感到陌生,通过应用上我们需要的所有要应用在redux流程上的中间件,我们可以加强dispatch的功能.最近也有一些初学者同时和实习生在询问中间件有关 ...
- Java日志正确使用姿势
前言 关于日志,在大家的印象中都是比较简单的,只须引入了相关依赖包,剩下的事情就是在项目中“尽情”的打印我们需要的信息了.但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的bug发生,作为一名 ...
- EIGRP 高级实验
一.环境准备 1. 软件:GNS3 2. 路由:c7200 二.实验操作 实验要求: 1.掌握EIGRP 的不等价均衡的条件. 2.掌握EIGRP 的metric 值修改方法. 3.掌握 EIG ...