为什么结构体数组比较有不同的结果

2024-03-08

我不知道为什么会发生以下情况,而且我找不到相关的源代码。有人能给我解释一下吗?

var s, ss struct{} // two empty structs
arr1 := [6]*struct{}{&s} // array with empty struct pointer
arr2 := [6]*struct{}{&ss} // array with empty struct pointer
fmt.Println(&s == &ss, arr1 == arr2)  // false, true

var l, ll struct{A int}{}
arr3 := [6]*struct{A int}{&l} // array with empty struct pointer
arr4 := [6]*struct{A int}{&ll} // array with empty struct pointer
fmt.Println(&l == &ll, arr3 == arr4)  // false, false

规格:比较运算符: https://golang.org/ref/spec#Comparison_operators

指针值具有可比性。如果两个指针值指向同一个变量或者都具有值,则它们相等nil. 指向不同的指针零尺寸 https://golang.org/ref/spec#Size_and_alignment_guarantees变量可能相等也可能不相等。

并且规格:尺寸和对齐保证: https://golang.org/ref/spec#Size_and_alignment_guarantees

如果结构体或数组类型不包含大小大于零的字段(或元素),则其大小为零。两个不同的零大小变量may在内存中具有相同的地址。

尺寸s and ss变量为零,所以&s and &ss是指向不同的零大小变量的指针,因此规范不保证它们的相等性。这意味着什么&s == &ss可以评估为true or false,你不能指望结果会是什么,这样做是错误的。

不过,奇怪的是,在应用程序的单个运行时期间,它们一次相等,一次不相等。教训是永远不要依赖它。

不同的行为可以通过查看逃逸分析来解释。

让我们将您的应用程序简化为:

var s, ss struct{}                   // two empty structs
arr1 := [6]*struct{}{&s}             // array with empty struct pointer
arr2 := [6]*struct{}{&ss}            // array with empty struct pointer
fmt.Println(&s == &ss, arr1 == arr2) // false, true

运行逃逸分析go run -gcflags '-m' play.go gives:

./play.go:13:17: &s == &ss escapes to heap
./play.go:13:30: arr1 == arr2 escapes to heap
./play.go:11:23: main &s does not escape
./play.go:12:23: main &ss does not escape
./play.go:13:14: main &s does not escape
./play.go:13:20: main &ss does not escape
./play.go:13:13: main ... argument does not escape
false true

&s and &ss不要逃避(因为它们没有传递给fmt.Println(),只有结果&s == &ss).

如果我们向上面的简化应用程序添加一行:

var s, ss struct{}                   // two empty structs
arr1 := [6]*struct{}{&s}             // array with empty struct pointer
arr2 := [6]*struct{}{&ss}            // array with empty struct pointer
fmt.Println(&s == &ss, arr1 == arr2) // true, true

fmt.Printf("%p %p\n", &s, &ss) // true, true

运行逃逸分析现在给出:

./play.go:13:17: &s == &ss escapes to heap
./play.go:13:30: arr1 == arr2 escapes to heap
./play.go:15:24: &s escapes to heap
./play.go:15:24: &s escapes to heap
./play.go:10:6: moved to heap: s
./play.go:15:28: &ss escapes to heap
./play.go:15:28: &ss escapes to heap
./play.go:10:9: moved to heap: ss
./play.go:11:23: main &s does not escape
./play.go:12:23: main &ss does not escape
./play.go:13:14: main &s does not escape
./play.go:13:20: main &ss does not escape
./play.go:13:13: main ... argument does not escape
./play.go:15:12: main ... argument does not escape
true true

行为发生了变化:我们现在看到true true输出(尝试在去游乐场 https://play.golang.org/p/6aGn3RZTmL2).

行为改变的原因是因为&s and &ss逃逸到堆:它们被直接传递到fmt.Println(),因此编译器改变了它们的存储方式(位置),随之而来的是它们的地址。

查看相关/可能的重复:空结构切片的 Golang 地址 https://stackoverflow.com/questions/48052722/golang-address-of-slices-of-empty-structs/48053270#48053270

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么结构体数组比较有不同的结果 的相关文章

  • C 中的链表数组:初始化和插入?

    我需要创建一个链表数组 如图所示 这就是我到目前为止所做的 typedef struct Node int data struct Node next Node int main void Node link 5 for int q 0 q
  • 将 C++ 数组传递给 Ada95

    我正在尝试将无符号整数数组从 C 传递到 Ada Ada Lovelace 教程指出 Ada 数组对应于 C 中指向数组第一个元素的指针 这就是我正在尝试做的事情 C unsigned int buffer bufferSize unsig
  • 如何为DNA序列生成一种热编码?

    我想为一组 DNA 序列生成一个热编码 例如 序列ACGTCCA可以以转置方式表示如下 但下面的代码将以水平方式生成一种热门编码 我更喜欢以垂直方式生成 谁能帮我 ACGTCCA 1000001 A 0100110 C 0010000 G
  • 从字符串中删除多个子字符串 - Java

    我需要从给定字符串中删除多个子字符串 例子 String exclude one two three String input if we add one and two we get three 我希望我的程序从输入字符串中删除所有出现的
  • 引用的地址总是等于原始地址吗?

    这看起来是一个非常基本的话题 但对我来说非常重要 以下示例显示引用变量的地址等于原始变量的地址 我知道这就是我们从 C C 的概念中可以期待的 然而 是不是始终保证这些地址在任何情况下都是相等的吗 include
  • 如何从 C 中的指针获取数组的大小?

    我分配了一个 数组 mystruct尺寸的n像这样 if NULL p calloc sizeof struct mystruct n 1 handle error 后来我只能访问p 并且不再有n 有没有一种方法可以确定仅给出指针的数组的长
  • 获取 Blob 图像并将该图像转换为 Bitmap 图像

    我正在从数据库中获取 blob 格式的图像 我想将其转换为位图图像 我用来将位图转换为 Blob 的代码放在下面 但是请告诉我如何反转它 ByteArrayOutputStream boas new ByteArrayOutputStrea
  • Perl:散列 2 中数组的数值排序(施瓦茨变换)

    这实际上是该线程的后续内容 Perl 散列中数组的数字排序 https stackoverflow com questions 7914931 perl numerical sort of arrays in a hash 我无法编辑原始问
  • 命名和未命名类型

    问题 我最近开始阅读Golang规格手册 https golang org ref spec并陷入试图理解的困境有名和无名类型在相关部分 https golang org ref spec Types 我来自动态语言 这让我有点头疼 手册指
  • 将单独的范围放入二维数组中

    我正在尝试获取大小的二维数组 x 3 填充 X只是工作表的大小 行数 并且有 3 列我感兴趣 例如 这些列彼此不靠近arr i 0 应从 AA 栏开始填写 arr i 1 应来自 K 列 并且arr i 2 需要来自 L 列 我尝试按以下方
  • 比较 BigQuery 中的表

    我如何比较两个表 Table1 and Table2 并查找所有新条目或更改Table2 使用 SQL Server 我可以使用 Select from Table1 Except Select from Table2 这是我想要的示例 T
  • 使用不同的阈值替换多列中的值

    我有一个包含多个列的数据集 其中包含我想要转换为二进制的定量数据 为此 我想使用每列不同的阈值 Example Input antigen1 antigen2 antigen3 antigen4 1 215 421 2 12 2 1524
  • 将行分组在一列上并与其他列形成嵌套子数组

    这是我试图处理的事情 我的数组看起来像这样并且有重复项 products product name gt Adidas1 address gt street 2 product name gt Adidas2 address gt stre
  • 将C++函数指针转换为C函数指针

    我正在使用 C 库开发 C 应用程序 我必须向 C 库发送函数指针 这是我的课 class MainWindow public QMainWindow Q OBJECT public explicit MainWindow QWidget
  • 是否可以在 Golang 中 pickle 结构实例

    我正在 Golang 中做一些机器学习 我现在碰壁了 我训练有素的分类器需要将近半分钟的时间来训练 并且想要保存分类器的该实例 这样我就不必每次都从头开始训练 在 Golang 中应该如何去做呢 仅供参考 我的分类器是一个结构 当我用 py
  • int arr[ ] 是有效的 C++ 吗?

    我试图理解是否写作int arr 在 C 中有效 举个例子 int a is this valid extern int b is this valid int ptrB is this valid struct Name int k is
  • Golang 从管道读取读取大量数据

    我正在尝试读取一个正在被焦油化 流式传输到标准输入的存档 但我正在以某种方式读取far管道中的数据多于 tar 发送的数据 我像这样运行我的命令 tar cf somefolder my go binary 源代码是这样的 package
  • 防止使用 golang 服务器访问文件夹中的文件

    我在 golang 中有一个服务器可以处理这样的文件夹路径 fs http FileServer http Dir assets http Handle Images fs http ListenAndServe 8000 nil 但在这个
  • 限制 FormFile 中的文件大小

    我让用户使用 FormFile 上传文件 我应该在什么时候检查文件大小是否太大 当我做 file header fileErr r FormFile file 文件对象已经创建 那么我是否已经产生了读取整个文件的成本 https golan
  • 相当于 JavaScript 中 Ruby 的each_cons

    许多语言都曾提出过这个问题 但 javascript 却没有 Ruby 有方法Enumerable each cons https devdocs io ruby 2 5 enumerable method i each cons看起来像这

随机推荐

  • 从 ADO.NET 执行 T-Sql 视图

    是否可以从 C 代码执行视图 如果是的话我想知道参数化视图是否存在以及我应该如何使用它们 参数化意味着我们在存储过程中使用相同的参数来声明 where 条件 不执行视图 一个执行查询 如果查询从视图或表中选择行 ADO NET 不知道也不关
  • Ruby on Rails / Paperclip / AWS::S3::NoSuchBucket 错误

    我安装了回形针插件并能够在本地使用它 当我将其配置为与 amazon S3 一起使用时 我不断收到 NoSuchBucket 指定的存储桶不存在 错误 回形针文档指出 如果存储桶不存在 则会创建该存储桶 但很明显 我的情况出了问题 我首先安
  • Mysql中如何将数据合并到临时表中

    我有一张非常大的桌子 叫做paypal ipn orders 在这个表中 我有 2 个重要的信息 一行称为item name和一行称为sort num 我想使用某些参数从中提取记录paypal ipn orders并将它们放入一个名为的临时
  • MS Access SQL 中是否有与 SUBSTRING 函数等效的函数?

    我想在 MS Access 查询中执行类似的操作 但 SUBSTRING 是一个未定义的函数 SELECT DISTINCT SUBSTRING LastName 1 1 FROM Authors 您可以使用 VBA 字符串函数 正如 on
  • Django静态媒体不显示图片

    在寻找解决方案几个小时后未能解决我的问题后 我发布了此内容 我的媒体根目录中的图像没有显示在我的 html 上 在 chrome 的控制台中我得到一个404 file not found 尽管图像就在那里 我在 Pycharm 中使用 Py
  • Google 日历 feed timeMin timeMax 不起作用

    我从搜索中推断 限制日期范围的 Google 日历提要的 URI 应包括 timeMin 和 timeMax 还应包括 singleEvents 和 orderBy 这是我构建的 URI 无论我在投影值后放置什么查询参数 我仍然会获取从 8
  • 以编程方式使下载停靠栏图标弹起

    如何以编程方式使 Dock 下载 图标弹起 请注意 我不希望我的应用程序图标弹起 而只希望下载图标弹起 特别是 我正在将文件从我的应用程序下载到 下载 文件夹 这没问题 但我希望下载图标在下载完成时弹起 就像 Safari 完成下载时发生的
  • 通过右值引用返回是否更有效?

    例如 Beta ab Beta toAB const return move Beta ab 1 1 Beta ab Beta toAB const return move Beta ab 1 1 这会返回一个悬空引用 就像左值引用的情况一
  • 多个鼠标/鼠标/光标?

    如何为多个鼠标显示另一个光标 我有两个 TMemo 两个可以输入各自 TMemo 的键盘 2 个鼠标 我需要 2 个光标 如果假设的话 我已经可以检测出哪只老鼠是哪只 我怎样才能让我自己的光标跟着它一起走 使用德尔福 可能沿着多点 http
  • 使用 bootstrap-datepicker 禁用日期范围?

    如何禁用多个日期范围 使用bootstrap datepicker 目前 这是我关于如何专门禁用日期的代码 div class input group input daterange div
  • Linux shell 编程字符串比较语法

    有什么区别 and 在Linux shell编程中比较字符串 也许下面的代码可以工作 if NAME user then echo your name is user fi 但我认为这不是正确的语法 它将用于比较字符串 陈述 什么是正确的
  • webpack --env.product 和 --mode="product" 之间有什么区别

    如果我错了 请纠正我 但据我从文档中了解到 env option https webpack js org guides environment variables 用来ONLY为了能够在webpack config js如果它导出一个函数
  • 插入表视图并添加按钮或空行时最好的是什么?

    当呈现一个简单的表格视图 或者我想甚至是列表视图 时 您输入新数据的首选方法是什么 With add delete buttons like this Or with a blank line indicating a new record
  • UIAlertViewDelegate 方法 didDismissWithButtonIndex 在手机睡眠/锁定时被调用

    我有一个 UIAlertView 它的 didDismissWithButtonIndex 委托方法调用会弹出视图控制器 同一类 它是 AlertView 委托和视图控制器 以使用户返回到上一个屏幕 问题是 当您在 警报显示 之前锁定手机时
  • Docker 化 Spring boot 应用程序以进行 Kubernetes 部署

    我有一个 Spring Boot 应用程序 在我的 application properties 中具有如下一些属性 server ssl keyStore users admin certs appcert jks server ssl
  • 顺时针旋转数组

    我有一个二维数组 需要顺时针旋转 90 度 但是我不断收到 arrayindexoutofbounds public int rotateArray int arr first change the dimensions vertical
  • ASP.NET Core + IIS + SSL

    如果我想在运行 IIS 作为反向代理的 ASP NET Core 应用程序中使用 https 我是否需要在 IIS 或 ASP NET Core 或两者中配置 SSL 证书 我的计划是在 IIS 上安装证书 这够了吗 在 IIS 上安装证书
  • PHP:数组有最大大小吗?

    PHP 中的数组有限制吗 是的 元素的最大数量有限制 哈希表结构 数组基本上是哈希表的包装器 定义如下 PHP 5 3 typedef struct hashtable uint nTableSize uint nTableMask uin
  • Tensorflow 1.9 / 对象检测:model_main.py 仅评估一张图像

    我已更新到 Tensorflow 1 9 和对象检测 API 的最新版本 当运行以前运行良好的训练 评估会话时 我认为版本 1 6 训练似乎按预期进行 但我只获得一个图像 第一个图像 的评估和指标 在 Tensorboard 中 图像标记为
  • 为什么结构体数组比较有不同的结果

    我不知道为什么会发生以下情况 而且我找不到相关的源代码 有人能给我解释一下吗 var s ss struct two empty structs arr1 6 struct s array with empty struct pointer