go 接口 构造器_Go 中接口值的复制

我一直在思考 Go 语言它是如何工作的。直到最近我才发现 Go 中一切都是基于值的。当我们向函数传递参数、迭代切片、执行类型断言时我们都可以看到这一现象。在这些例子中,这些数据结构所存储的值的拷贝会被返回。当我刚开始学习 Go 的时候,我对于这种实现方式很失望,但渐渐地我开始意识到这样做对于我们的代码来说有它的合理性。

我开始在想,如果我创建了一个所存储的是值而非指针的接口类型的拷贝会发生什么。那么这个新的接口值会拥有自己新的副本值,还是共享原来的值?为了验证我的猜想,我写了一个小程序来检查接口值。

https://play.golang.org/p/KXvtpd9_29

清单 1

06 package main
07
08 import (
09     "fmt"
10     "unsafe"
11 )
12
13 // notifier provides support for notifying events.
14 type notifier interface {
15     notify()
16 }
17
18 // user represents a user in the system.
19 type user struct{
20     name string
21 }
22
23 // notify implements the notifier interface.
24 func (u user) notify() {
25     fmt.Println("Alert", u.name)
26 }

在清单 1 的代码中第 14 行,我们声明了一个具有 notify 方法的接口类型 notifier。在 19 行我们声明了一个 user 类型,这个类型在 24 行实现了 notifier 接口中的 notify 方法。现在我们拥有了一个接口类型和一个实现类型。

清单 2

28 // inspect allows us to look at the value stored
29 // inside the interface value.
30 func inspect(n *notifier, u *user) {
31     Word := uintptr(unsafe.Pointer(n)) + uintptr(unsafe.Sizeof(&u))
32     value := (**user)(unsafe.Pointer(word))
33     fmt.Printf("Addr User: %p  Word Value: %p  Ptr Value: %vn", u, *value, **value)
34 }

在清单 2 中我们在 30 行写了一个检查的函数。这个函数返回给我们一个指向接口值的第二个字的指针。通过这个指针我们可以检查此接口第二个字的值,以及第二个字指向的 user 值。我们需要审查这些值来真正理解接口的机制。

清单 3:

36 func main() {
37
38     // Create a notifier interface and concrete type value.
39     var n1 notifier
40     u := user{"bill"}
41
42     // Store a copy of the user value inside the notifier
43     // interface value.
44     n1 = u
45
46     // We see the interface has its own copy.
47     // Addr User: 0x1040a120  Word Value: 0x10427f70  Ptr Value: {bill}
48     inspect(&n1, &u)
49
50     // Make a copy of the interface value.
51     n2 := n1
52
53     // We see the interface is sharing the same value stored in
54     // the n1 interface value.
55     // Addr User: 0x1040a120  Word Value: 0x10427f70  Ptr Value: {bill}
56     inspect(&n2, &u)
57
58     // Store a copy of the user address value inside the
59     // notifier interface value.
60     n1 = &u
61
62     // We see the interface is sharing the u variables value
63     // directly. There is no copy.
64     // Addr User: 0x1040a120  Word Value: 0x1040a120  Ptr Value: {bill}
65     inspect(&n1, &u)
66 }

清单 3 展示了从 36 行开始的主函数。 我们做的第一件事情就是在 39 行声明了类型为 notifier 名为 n1 的接口变量,将其设为初始零值。然后在 40 行我们声明了一个类型为 user 的变量 u,其初始值为 bill

我们想要在将具体 user 值分配给接口之后,检查这个接口值的第二个字包含什么。

清单 4

42     // Store a copy of the user value inside the notifier
43     // interface value.
44     n1 = u
45
46     // We see the interface has its own copy.
47     // Addr User: 0x1040a120  Word Value: 0x10427f70  Ptr Value: {bill}
48     inspect(&n1, &u)

插图 1:当我们将 user 的值分配给该接口之后,这个接口内部结构是什么样的。

0e5f37fc2d672d9ad226af777c1937d9.png

插图 1 向我们展示了在分配后接口的内部结构视图。我们可以看到这个接口有它自己的 user 值的拷贝。存储在接口值内部的 user 值的地址和原始 user 值的地址并不相同。

我编写这段代码用来了解如果我创建了一个分配了值而非指针的接口值的副本会发生什么。新的接口值是否也有自己的副本,或者值是否会共享。

清单 5

50     // Make a copy of the interface value.
51     n2 := n1
52
53     // We see the interface is sharing the same value stored in
54     // the n1 interface value.
55     // Addr User: 0x1040a120  Word Value: 0x10427f70  Ptr Value: {bill}
56     inspect(&n2, &u)

插图 2:当接口值被拷贝后,这两个接口值的内部构造。

548bf29138f414650c0b9a11cb9e5145.png

插图 2 给了我们答案。当我们创建一个接口值的拷贝时,这就是我们复制的全部内容。原来存储在 n1 中的 user 值此时也共享给了 n2。每个接口值并没有获得它们独有的拷贝。它们共享了同一个 user 值。

如果我们分配的是 user 值的地址而不是该值本身,那么所有这些情况都会有所改变。

清单 6

58     // Store a copy of the user address value inside the
59     // notifier interface value.
60     n1 = &u
61
62     // We see the interface is sharing the u variables value
63     // directly. There is no copy.
64     // Addr User: 0x1040a120  Word Value: 0x1040a120  Ptr Value: {bill}
65     inspect(&n1, &u)

插图 3: 当我们为接口分配了一个地址时,该接口值的内部构造。

b79d7545c2dfedfffccf9a79361ff81b.png

在插图 3 中,我们看到该接口现在指向的是被变量 u 引用的 user 值。 变量 u 的地址已经存储到这个接口值的第二个字当中。这就意味着和 user 值相关的任何变化都会影响到这个接口值。

结论

我允许自己对 Go 在创建一个接口值的拷贝时,只存储值而不是指针的情况感到困惑。有那么一瞬间,我想知道接口值的每个副本是否也创建了接口引用的值的副本。因为我们“存储”了一个值而不是一个指针。但我们现在学到的是,由于地址始终会被存储起来,因此它是被复制的地址,而不是值的本身。


via:Go 中接口值的复制 - Go语言中文网 - Golang中文社区

作者:William Kennedy 译者:barryz 校对:polaris1119

本文由 GCTT 原创编译,Go语言中文网 荣誉推出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【人工智能】人工智能革命与机遇

来源 | 北大AI公开课编辑 | Vincent、Natalie课程导师:雷鸣,天使投资人,百度创始七剑客之一,酷我音乐创始人,北京大学信科人工智能创新中心主任,2000年获得北京大学计算机硕士学位,2005年获得斯…

laravel log 对象_swoole运行模式加速laravel应用的详细介绍(life)

本篇文章给大家带来的内容是关于swoole运行模式加速laravel应用的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。我的官方群点击此处。一、SwooleSwoole号称重新定义了PHP,它是一个PHP扩展,使…

OVS+DPDK Datapath 包分类技术

本文主体内容译于[DPDK社区文档],但并没有逐字翻译,在原文的基础上进行了一些调整,增加了对TSS分类器的详细阐述。 1. 概览 本文描述了OVSDPDK中的包分类器(datapath classifier -- aka dpcls)的设计与实现思路。本文的内容主要牵涉到分类器对…

mysql第五章 在线测试_PHP+MySQL来实现在线测试quiz功能

在上一篇文章中,我们介绍了jQuery前端PHP在线测试题效果。这篇文章将结合实例给大家介绍如何使用jQueryPHPMySQL来实现在线测试题,包括动态读取题目,答题完毕后台评分,并返回答题结果。查看演示下载资源:1332次 下载资…

深度揭秘AI换脸原理,为啥最先进分类器也认不出?

文章来源:VentureBeat,arXiv智东西4月20日消息,AI换脸已不是新鲜事,手机应用市场中有多款换脸app,此前也曾曝出有网络IP用明星的面孔伪造色情影片、在大选期间用竞选者的脸制作虚假影像信息等。为了规避Deepfake滥用带…

中美德工业互联网路径比较

转自丨无锡情报所作者丨王喜文,九三学社中央促进技术创新工作委员会委员、九三学社中央科技委委员过去20年,互联网是改变社会、改变商业最重要的技术;如今,随着5G、物联网以及云计算和大数据、区块链、人工智能技术的迅速发展&…

不同浏览器隐藏默认表单样式

各种appearance: none; 转载于:https://www.cnblogs.com/haimingpro/p/7168738.html

jmeter file upload 变量_通达OA上传漏洞之变量覆盖分析

作者:kw0ng开始通达OA上传到包含漏洞分析的文章已经有很多,本文重点分析,文件上传处决定路径信息是否回显的UPLOAD_MODE参数是怎么传递的。代码分析触发文件上传点位于/ispirit/im/upload.php中,服务端在接收文件信息的同时还需要…

如果卷积神经网络存在根本性的缺陷,你会怎么看?

来源:人工智能头条作者 | Ben Dickson译者 | 香槟超新星经过一段漫长时期的沉寂之后,人工智能正在进入一个蓬勃发展的新时期,这主要得益于深度学习和人工神经网络近年来取得的长足发展。更准确地说,人们对深度学习产生的新的兴趣在…

产业|嵌入式传感器将是未来机器人等技术增长的核心

来源:EEWORLD移动即服务(MaaS)被认为是智能移动的一个关键要素,而机器人汽车技术将是智能移动的一个重要因素,它又高度依赖于嵌入式传感器。根据市场研究和战略咨询公司Yole development pement (Yole)的预测,在这种情况下&#x…

可观测宇宙中,我们可能是唯一的生命

图片来源:Pixabay长期以来,人类一直渴望在宇宙中找到地外生命的痕迹,但一项于今年早些时候发表的研究,给持有此类想法的人泼了一盆冷水。基于“自然发生”学说以及其中的“RNA世界”假说,研究人员认为在可观测宇宙中&a…

中国工程院发布“中国电子信息工程科技发展十六大挑战”

来源:通信世界全媒体通信世界网消息(CWW)为响应中央决策部署,推进我国新型数字基础设施建设,推动我国电子信息工程科技领域高质量发展,助力数字基建科学发展驱动壮大经济新动能。4月26日,中国工程院信息与电子学部、中…

Unix下5种I/O模型

Unix下I/O模型主要分为5种: (1)阻塞式I/O (2)非阻塞式I/O (3)I/O复用(select和poll) (4)信号驱动式I/O (5)异步I/O 1、阻塞式I/O模型 unix基本的套…

2019年智能科学与产业综述论文盘点

来源:计算机研究与发展2019年综述论文盘点1.智能芯片的评述和展望(韩栋,周聖元,支天,陈云霁,陈天石)2.闪存存储的重构与系统构建技术(陆游游,杨者,舒继武)3.基于动态权衡的新型非易失存储器件体系结构研究综述&#xf…

h命令可以获取mysql客户端的帮助信息_如何获取MySQL帮助信息

在开发或测试环境在碰到MySQL相关故障时,大多数朋友可能会通过论坛发帖,QQ群讨论方式来获取帮助。该方式是获取帮助的有效途径之一。然而如果在生产环境,在没有网络的环境下,这些方式就无助于问题的解决。无论何种数据库&#xff…

AI与人类围棋士的差距到底有多大?

来源:计算广告四年前,谷歌旗下DeepMind公司开发的围棋人工智能AlphaGo以4-1战胜韩国大国手李世乭九段。今天,AlphaGo在大众视野中掀起的惊涛骇浪已渐平息,AlphaGo和李世乭都已从江湖退隐。然而,围棋界因AlphaGo而起的沧…

mariadb使用mysql驱动_MariaDB安装与使用

下载相对应的电脑版本程序等待下载完成......安装教程:双击运行设置数据库的密码等待安装完成..这样就完成安装了。安装完成,会在桌面生成这个图标双击可以直接使用下面我通过两种方式来使用MariaDB数据库(可视化,命令行)通过可视化方式使用。…

脑机接口技术重大突破!首次帮助瘫痪男子恢复运动和触觉

来源:网易智能触觉是我们感受外部世界不可或缺的感官,但许多人却因脊髓损伤或因患病瘫痪而失去这种能力。不过,最近非营利组织巴特尔研究所的研究人员宣称,他们首次利用脑机接口(BCI)技术帮助一名美国瘫痪男…

python海龟图画龙珠_火影,海贼王,七龙珠,还在为漫画书发愁!我用Python一键生成电子漫画书...

小时候看漫画都是要买书的,一本好几块钱,成本那个高啊后来可以在线看漫画,感觉真是爽不过近几年新的问题又出现了:漫画网站广告太多,更重要的是越来越多的作品、章节出于各种原因被下架、限制观看。为了提升观看体验&a…

谷歌自揭“家丑”:医疗AI实验室表现超神,临床结果却不佳

来源:澎湃新闻在医疗领域,尤其是在医学影像筛查过程中,人工智能常被描述为完美的工作者。它们能准确识别疾病,拥有人类专家级的发现能力,还不知疲倦。但与许多技术一样,在实验室取得成功是一回事&#xff0…