方法上的指针和值之间的区别

方法上的指针和值之间的区别

在 go 中编写方法时,关键决策之一是是按值还是按指针传递结构体。此选择会影响性能、代码行为和内存分配。在这篇文章中,我们将通过实际示例探讨这种差异,并了解每种方法何时更合适。

让我们从一个小结构体和两个方法开始:一个结构体通过值传递,另一个通过指针传递。

package mainimport (    "fmt")type person struct {    name string    age  int}// method with struct passed by valuefunc (p person) celebratebirthdayvalue() {    p.age++}// method with struct passed by pointerfunc (p *person) celebratebirthdaypointer() {    p.age++}func main() {    person := person{name: "alice", age: 30}    // passing by value    person.celebratebirthdayvalue()    fmt.println("after celebratebirthdayvalue:", person.age) // output: 30    // passing by pointer    person.celebratebirthdaypointer()    fmt.println("after celebratebirthdaypointer:", person.age) // output: 31}

登录后复制

值和指针之间的区别

当我们将结构体按值传递给方法时,go 会创建该结构体的副本。对方法内的结构体进行的任何更改都不会影响原始结构体,因为我们正在使用独立的副本。

另一方面,当我们通过指针传递结构体时,我们传递的是原始结构体的内存地址。这意味着对方法内的结构体所做的任何更改都将直接修改原始结构体,因为我们正在操作同一个实例。

总结:

按值: 该方法接收结构体的副本,创建一个新的内存空间。

通过指针:该方法接收原始结构体的内存地址,指向同一内存空间。

当结构按值传递时,副本会在堆栈上分配,这通常是快速且高效的。但是,如果结构很大,则副本可能会消耗大量堆栈内存。

当通过指针传递结构时,指针本身会在堆栈上分配,但原始结构可能会在堆上分配,特别是当它是使用 new、make 创建或由匿名函数捕获时。

堆分配在分配时间和垃圾收集方面更昂贵,但允许高效操作大量数据,而无需复制整个结构。

何时使用每种方法

按价值

按值传递结构在以下情况下很有用:

您要确保原始结构不被修改。结构体很小,复制它不会显着影响性能。该方法只需读取数据,无需更改内部状态。

示例:

func (p person) getname() string {    return p.name}

登录后复制

这里,getname 只读取 name 字段并返回一个字符串,而不修改结构体的状态。

通过指针

在以下情况下通过指针传递结构是有益的:

需要修改原来的结构体。该结构体很大,复制其数据在内存和性能方面的成本很高。您希望避免不必要的副本以提高代码效率。

示例:

func (p *Person) UpdateName(newName string) {    p.Name = newName}

登录后复制

在这种情况下,updatename 直接修改原始结构体的 name 字段,这比创建副本更高效。

结论

在 go 中编写方法时决定是按值还是按指针传递结构体是一个重要的选择,可能会影响性能、代码行为和内存分配。

按值传递对于确保方法内结构的不变性很有用,而按指针传递对于修改原始结构并在处理较大结构时优化性能至关重要。

以上就是方法上的指针和值之间的区别的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2311323.html

(0)
上一篇 2025年2月28日 12:20:24
下一篇 2025年2月26日 20:52:37

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 如何在 VS Code 中配置 Delve (dlv)

    让我们深入研究与 vs code 的集成! 首先你需要安装delve (dlv): go install github.com/go-delve/delve/cmd/dlv@latest 登录后复制 您可以通过运行来验证它的安装位置: wh…

    2025年2月28日
    200
  • A接口写入

    在 go 中,接口是促进多态性和抽象的基础。它们充当契约,指定类型必须实现的一组方法,允许以统一且灵活的方式处理不同的类型。 接口 在 go 中,接口是一种定义一组方法但不实现它们的类型。它仅指定类型必须满足接口的方法签名。这允许不同的类型…

    2025年2月28日
    200
  • 掌握 Go 中的 ENUM

    通常,在我们开发的系统中,我们会遇到恒定的值。这些值的一个示例可以是注册状态的表示。在这种情况下,请考虑包含除活动和非活动之外的更多变化的状态。 如果这些状态被定义为字符串,它们在系统内的验证可能会成为一个令人头疼的问题。此外,这种方法可能…

    2025年2月28日
    200
  • [DevLog # Gmail-TUI:复制 Gmail-Web 导航

    感谢之前 devlog 上的所有支持,我带着 gmail-tui 应用程序的最新更新回来了!如果您不知道这个开源项目,我正在开发一个基于终端的 ui 应用程序,旨在在终端中复制 gmail-web 体验,而不需要 web 浏览器: 阅读开发…

    2025年2月28日
    200
  • Go 的泛型:编写适用于多种类型的更智能的代码

    泛型即将进入 go,这是一件大事。我一直在深入研究 go 2 的拟议更改,并且很高兴分享我对这一强大新功能的了解。 从本质上讲,泛型允许我们编写适用于多种类型的代码。我们可以编写一个通用函数来处理所有这些类型,而不是为整数、字符串和自定义类…

    2025年2月28日
    200
  • 使用 Go 处理大型 CSV

    想法是: 给定一个大型虚拟 csv(100 万行)包含客户数据样本,并按照以下目标进行处理: 从 csv 中提取数据计算有多少数据/行对每个城市的客户数量进行分组按客户数量从高到低对城市进行排序计算处理时间 客户的 csv 示例可以在此处下…

    2025年2月28日
    200
  • 用 Go 构建可扩展的 SQS 消费者

    介绍 在构建分布式系统时,像 amazon sqs 这样的消息队列在处理异步工作负载方面发挥着至关重要的作用。在这篇文章中,我将分享我在 go 中实现强大的 sqs 消费者的经验,该消费者可以处理 keycloak 的用户注册事件。该解决方…

    2025年2月28日
    200
  • 掌握 Go 的并发性:使用 Goroutines 和 Channel 增强您的代码

    goroutines 和 channels 是 go 并发模型的支柱。它们不仅仅是简单的工具;它们是强大的结构,可以让我们构建复杂的高性能系统。 让我们从 goroutine 开始。它们就像轻量级线程,但效率更高。我们可以毫不费力地繁殖数千…

    2025年2月28日
    200
  • 如何在 Vercel 中托管 Hugo

    我决定和hugo一起建立我的个人网站。我的选择唯一基于的是构建时间。我认为 hugo 在内容管理方面与 astro 处于同一水平,但目前还没有达到这个水平。或者,我可以说它有自己的路径,因为它比我遇到的大多数其他静态站点生成器都要旧。此外,…

    2025年2月28日 编程技术
    200
  • 使用 Go 构建安全的 RAG 应用程序:GoRag 简介

    在快速发展的人工智能开发领域,检索增强生成 (rag) 已成为利用上下文信息增强大型语言模型 (llm) 响应的关键技术。虽然 python 在 ai/ml 生态系统中占据主导地位,但对系统编程语言中强大的、生产级 rag 实现的需求日益增…

    2025年2月28日
    200

发表回复

登录后才能评论