传递结构体和结构体指针有什么区别,它们不都是指针吗?

2024-02-18

例如

var myStructRef *Vertex
var myStruct Vertex
myStructRef = &Vertex{2, 3}
myStruct = Vertex{2, 3}

fmt.Println(myStructRef)
fmt.Println(myStruct)
changeByReferenceStruct(myStructRef)
changeByValueStruct(myStruct)
fmt.Println(myStructRef)
fmt.Println(myStruct)

And

func changeByValueStruct(myStruct Vertex) {
    myStruct.X = 5
    fmt.Println(myStruct)
}


func changeByReferenceStruct(myStruct *Vertex) {
    myStruct.X = 7
    fmt.Println(myStruct)
}

不是两者兼而有之myStructRef *Vertex and myStruct Vertex指向结构本身的指针?当我修改函数中的结构时,为什么会出现行为差异?

golang 是否创建了一个新结构changeByValueStruct什么时候解析参数?


当您将指针作为参数传递时,幕后发生的事情是创建该指针的副本并将其传递给底层函数。不应将其与引用传递相混淆。

让我们看一个例子以更好地理解它:

package main

import (
    "fmt"
)

type Point struct {
    x int
    y int
}

func (p Point) String() string {
    return fmt.Sprintf("(%d, %d)", p.x, p.y)
}

func modifyValue(point Point) {
    point.x += 10
}

func modifyPointer(point *Point) {
    point.x = 5
    point.y = 5
}

func modifyReference(point *Point) {
    point = &Point{5, 5}
}

func main() {
    p := Point{0, 0}
    fmt.Println(p) // prints (0, 0)
    
    modifyValue(p)
    fmt.Println(p) // prints (0, 0)
    
    modifyPointer(&p)
    fmt.Println(p) // prints (5, 5)
    
    p = Point{0, 0}
    modifyReference(&p)
    fmt.Println(p) // prints (0, 0)
}

里面发生了什么修改值函数的区别在于修改了一个完全不同的 Point 结构实例,因此调用该函数时传递的值不受影响。

在第二个示例中,传递了指向结构的指针,因此可以以从外部可见的方式修改结构的字段。

最有趣的一点是最后一个函数,修改参考。如果您熟悉其他语言中可用的引用传递范例,您将期望能够完全修改引用的对象,但这不会发生。这是因为你正在修改一个copy作为参数传递的指针。

您可能想知道,如果所有内容都按值传递,那么什么时候应该传递指针以及什么时候应该传递值。传递值可以向调用者函数保证传递的结构不会遭受任何更改,因此当您需要这种行为时,请选择该值。这样做的缺点是会创建整个对象的副本,如果它太大,内存就会成为问题。

如果您将一个大结构作为参数传递,那么使用指针更好,因为它节省空间,但您失去了对象不会遭受任何更改的保证。

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

传递结构体和结构体指针有什么区别,它们不都是指针吗? 的相关文章

  • 错误:标准包中非标准导入“gopkg.in/yaml.v2”

    我正在尝试从以下位置导入 go yamlhttps github com go yaml yaml https github com go yaml yaml 并且我发现了一个 Google 没有提供帮助的错误 I ran go get g
  • golang无法启动调试,显示未找到框架CoreFoundation

    我使用的是 Macbook pro m1 在数据迁移或更新到 monterey 后 不确定是什么原因导致的 golang 似乎无法调试或 go list 编译 我尝试重新安装 更新 golang 结果是一样的 Go版本 1 17 3 dar
  • 实现具有更广泛方法签名的接口

    在Go中 是否有一种方法可以使用方法来实现接口 其中实现中相应方法的返回类型 比 预期返回类型 更宽 这很难解释 所以这里有一个例子 在 Go Playground 中运行以下示例代码时出现此错误 prog go 36 14 cannot
  • 什么时候返回结构体指针是个好主意?

    我正在学习 Go 我对何时使用指针有点困惑 具体来说 当返回一个struct从函数中 什么时候适合返回结构体实例本身 什么时候适合返回指向结构体的指针 示例代码 type Car struct make string model strin
  • 关闭长度未知的通道

    当不了解频道时我无法关闭频道 length package main import fmt time func gen ch chan int var i int for time Sleep time Millisecond 10 ch
  • Facebook服务器端登录、CORS

    我正在实现一个带有 FB 服务器端登录的网站 简化步骤如下 一个简单的按钮触发 JS 脚本 该脚本调用我的后端 APIhttps localhost fblogin function sendFbLoginData get https lo
  • 将数组显式衰减为指针

    最简洁 最惯用的方式是什么明确地将数组衰减为指针 例如 考虑您需要能够指导 SFINAE 或明确过载的情况 template
  • 带 ref 参数的委托

    有没有办法在下面的代码中维护相同的功能 但不必创建委托 我正在与第 3 方 API 进行交互 其中包含许多不同的 DeleteSomethingX ref IntPtr ptr 方法 并且我正在尝试集中 IntPtr Zero 检查的代码
  • 为什么C++中没有“NULL引用”?

    我正在阅读 C 常见问题解答 8 6 什么时候应该使用引用 什么时候应该使用指针 http www parashift com c faq lite refs vs ptrs html 特别是以下声明 可以时使用引用 必要时使用指针 上述情
  • 关于编写惯用的 Golang 的建议

    我正在掌握 Golang 的做事方式 首先是一些示例代码 package main import log os func logIt s string f os OpenFile errors log os O RDWR os O CREA
  • 为什么 DER ASN.1 大整数的解组在 Golang 中仅限于 SEQUENCE?

    我希望能够使用encoding asn1 包从 DER 文件中解组一个大整数 但它看起来只适用于整数序列 例如 这不起作用 这很奇怪 因为 Big Int 的编组效果很好 https play golang org p Wkj0jAA6bp
  • 将数组复制到动态分配的内存

    我的代码可以正常工作 但我觉得好像有一种更快的方法可以做到这一点 特别是在我的函数副本中 这是我的代码 这能再快一点吗 顺便说一句 这是 C 语言 另外 当我从函数返回 cpy 时 它是否会删除动态内存 因为它超出了范围 我不想发生内存泄漏
  • 将 Option<&mut T> 转换为 *mut T

    我正在围绕 C 库编写一个 Rust 包装器 同时我试图利用中提到的 可空指针优化 The Book https doc rust lang org 1 30 0 book first edition ffi html the nullab
  • 如何明智地解释这个编译器警告?

    当我执行这段代码时question https stackoverflow com a 51056490 2411320 我收到这个警告 warning format d expects argument of type int but a
  • Go 指针 - 通过指针将值附加到切片

    我有一个 struct ProductData 及其实例 p 它有一个切片属性 type ProductInfo struct TopAttributes map string interface 我想设置 TopAttributes 如下
  • 结构体到磁盘的高效 Go 序列化

    我的任务是将 C 代码替换为 Go 而且我对 Go API 还很陌生 我正在使用 gob 将数百个键 值条目编码到磁盘页面 但 gob 编码有太多不需要的膨胀 package main import bytes encoding gob f
  • 为什么使用数组索引循环数组比指针访问慢?

    我正在读Kochan的书 Programming in C 在第 14 页的 指针和数组 部分中 264 他说 一般来说 索引数组的过程比执行索引过程花费更多的时间 访问指针内容的过程 其实这也是主要原因之一 为什么使用指针来访问数组的元素
  • Golang:如何在HTTP客户端的TLS配置中指定证书

    我有一个证书文件 该位置是 usr abc my crt我想将该证书用于我的 tls 配置 以便我的 http 客户端在与其他服务器通信时使用该证书 我当前的代码如下 mTLSConfig tls Config CipherSuites u
  • 仅导出嵌入结构实现的方法子集

    是否可以仅导出嵌入结构实现的方法的子集 这是一种与减少代码复制和粘贴非常不同的方法吗 还有更惯用的方法吗 type A struct func a A Hello fmt Println Hello func a A World fmt P
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐

  • Django Rest 框架和文件上传

    我正在尝试使用 DRF 和 jQuery 构建文件上传 我用谷歌搜索发现这个样本 https stackoverflow com a 27305713 1907902 我在后端有一些类似的代码 class Attachment BaseMo
  • 如何在命令行中调用内置产品打包实用程序

    当您在构建设置 Xcode 4 2 1 中指定权利和代码签名身份时 从 Xcode 构建时您将获得以下输出 ProcessProductPackaging myAppName entitlements path to myAppName x
  • 什么是“部署 ID”和“部署唯一名称”

    我不明白 Azure 云服务的 部署 ID 和 部署唯一名称 是什么 Azure Powershell 工具似乎会自动生成它们 但它们的用途是什么 如何使用它们 当 部署槽 不够用时 在什么意义上部署名称是 唯一的 部署ID是 Window
  • 斯坦福核心 NLP 是否支持德语词形还原?

    我发现了与斯坦福核心 NLP 兼容的德语解析和后标记模型 但是我无法使德语词形还原工作正常进行 有办法这样做吗 抱歉 据我所知 Stanford CoreNLP 不存在德语词形还原的实现
  • PHP - 如何重命名对象属性?

    我想知道如何在 PHP 中重命名对象属性 例如
  • 使用 ESM 在浏览器中动态或静态导入 json

    我运行以下示例 而 JS 之上没有捆绑器 index js async gt const mod await import index json console log mod file index json Chrome 80 无法加载
  • Django:员工装饰者

    我正在尝试为 Django 编写一个 仅限员工 的装饰器 但我似乎无法让它工作 def staff only error Only staff may view this page def dec view func def view re
  • 两个复杂度 O((2n + 1)!) 和 O(n!) 相等吗?

    这可能是一个幼稚的问题 但我对 Big O 表示法和复杂性的概念很陌生 无法找到任何答案 我正在处理一个算法 2n 1 次检查条件 我可以说问题的复杂度是 O n 还是复杂度是 O 2n 1 Use 斯特林近似 http en wikipe
  • JAVA中存储二维数组的数据结构

    我正在寻找一种数据结构来存储二维整数数组 List 是正确的数据结构还是我应该使用另一种数据结构 有人可以给我一个关于如何创建这样的数据结构以及如何添加二维数组的简短示例吗 编辑 我想要一个数据结构 在其中存储 int 11 7 数组 例如
  • MySQL 中 BLOB 到长文本的转换

    我在 MySQL 中有一个数据类型为 BLOB 的列 我正在使用 Crystal Reports 来生成一些报告 我的问题是 BLOB 列如果包含图片以外的数据 将显示空白数据 我从数据库获取的数据只是文本 所以我想将 BLOB 列转换为其
  • 无法从设备存储中删除文件android

    我正在开发一个笔记应用程序 其中列表视图在将笔记存储在由我的实用程序类控制的内部存储中后显示笔记 我刚刚在上下文菜单中实现了删除选项 删除选项可以很好地删除每个选定的列表视图项目 但是 当我刷新列表活动或添加新注释时 已删除的注释不断重新出
  • 一旦我将项目添加到 XCode 4.0.2,它就会崩溃

    它给出了这个错误 ASSERTION FAILURE in SourceCache IDEXcode3ProjectSupport IDEXcode3ProjectSupport 269 Xcode3Sources XcodeIDE Fra
  • 如何使用 jszip 库压缩文件

    我正在开发一个使用 HTML5 和 jquery 的移动离线应用程序 我想使用 jszip 从本地存储备份文件 下面是我所做的代码片段 if localStorageKeys length gt 0 for var i 0 i lt loc
  • android:覆盖来电屏幕

    我想在来电屏幕上添加一些附加信息 为此 在我的应用程序中 我正在检查 PHONE STATE 并在 RINGING 上 我正在调用一项活动 在此活动中 我设置如下文本视图 它按预期工作 文本将添加到来电屏幕 问题是 如果我在我的应用程序中
  • 使用正则表达式和 re 获取括号之间的文本

    我有一个字符串数组 我想从中提取特定内容 link description button text 我想得到以下输出 link description button text 对于数组中的每个字符串 我执行以下操作 str re finda
  • Create-React-App:从 node_module 目录包含 CSS 的最佳方法是什么

    我正在尝试在我的 create react app 项目中包含一些 CSS CSS 来自第 3 方 NPM 包 因此位于 node modules 目录中 我试过 import node modules packagename css st
  • 尽管超时很长,PHP 仍丢失 mongoDB 游标

    我正在运行一个长 mongoDB 查询 如下所示 foreach xyz gt find gt timeout 24 60 60 1000 gt maxTimeMS 24 60 60 1000 as document 但是 尽管客户端和服务
  • 更改单选按钮旁边的文本字体?

    要更改我使用的 textView 的字体 TextView tv TextView findViewById R id textview Typeface font Typeface createFromAsset getAssets SF
  • #selector' 指的是未暴露给 Objective-C swift 3 的方法

    我正在使用 Xcode 8 和 swift 3 我在 let action 行上出现以下错误 selector 指的是不暴露给Objective C的方法有什么建议吗 override func tableView tableView UI
  • 传递结构体和结构体指针有什么区别,它们不都是指针吗?

    例如 var myStructRef Vertex var myStruct Vertex myStructRef Vertex 2 3 myStruct Vertex 2 3 fmt Println myStructRef fmt Pri