如果对象位于切片中,方法不会更改对象的值

2024-01-16

这是我的程序:

package main

import (
    "fmt"
)

type Number struct {
    val int
}

func (num * Number) Increment () {
    num.val += 1
}

func (num Number) Value() int {
    return num.val
}

func main() {
    numbers := []Number {
        {val: 12}, 
        {val: 7},
        {val: 0},
    }

    for _, each := range numbers {
        each.Increment()
        fmt.Println(each.Value())
    }

    for _, each := range numbers {
        fmt.Println(each.Value())
    }
}

这是输出:

13
8
1
12
7
0

第一个问题:为什么Increment()方法不更新第一个 for 循环中的值?我使用指针作为接收器,这样val肯定可以更新,但为什么第二个for循环打印出这些的原始值Numbers?

第二个问题:当我迭代切片时可以做什么Numbers 并调用Increment()方法,全部Numbers 是否正确递增?

[Edit]我注意到如果我使用基于索引for循环并调用Increment()方法,值将被正确更新。为什么?

for i := 0; i < len(numbers); i++ {
    numbers[i].Increment()
}

This for range loop:

for _, each := range numbers {

迭代的元素numbers切片,并在每次迭代中分配 (copies) 的一个元素each循环变量。

自从你的numbers切片的类型是[]Number,它将复制Number构造成each变量(其类型为Number).

然后你调用Number.Increment()方法对此变量。自从Increment()有指针接收器,这是一个简写(&each).Increment()。因此,该循环变量的地址被用作Increment()方法。这Increment()方法将正确更改此循环变量,但这是独立的、不同的、与切片分离的,因此您不会修改切片中的元素。

当你这样做时:

for i := 0; i < len(numbers); i++ {
    numbers[i].Increment()
}

要点numbers这里就不复制了。这:

numbers[i].Increment()

索引numbers切片,并且由于Increment()有一个指针接收器,地址为numbers[i]被取出并使用,即元素的地址在切片中。所以在这里,您将修改Number切片的结构体值。

请注意,您还可以使用for range here:

for i := range numbers {
    numbers[i].Increment()
}

在切片上进行范围变化时的第一个迭代变量是索引。

另外,如果您将指针存储在numbers切片(然后其类型为[]*Number),同样的事情也会发生,但在这种情况下for range将复制指针,而不是结构,并且循环变量中的指针将指向相同的Number结构值就像切片中的指针一样,因此这也适用于您的第一个for range变体。

所有这些都详细说明在规格:用于报表 https://golang.org/ref/spec#For_statements, 在里面对于带有范围子句的语句小节。

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

如果对象位于切片中,方法不会更改对象的值 的相关文章

  • 双向链表中的成员访问

    我目前正在阅读 编程 使用 C 的原理与实践 的第 17 章 但我无法弄清楚 在下面的代码中 该行的作用是什么norse gods gt succ gt prev norse gods实际上呢 我知道 gt 是一个成员访问运算符 给定一个指
  • 如何使用 go web 服务器提供静态 html 文件?

    如何使用 go web 服务器提供 index html 或其他静态 HTML 文件 我只想要一个基本的静态 HTML 文件 例如一篇文章 我可以从 Go Web 服务器提供该文件 HTML 应该可以在 go 程序之外进行修改 就像使用 H
  • 初始化变量以减少 OMP

    OpenMP 标准指定了缩减变量的初始值 那么我是否必须初始化该变量以及在以下情况下如何执行此操作 int sum for int it 0 i
  • C# 数组如何存储在内存中

    我想我的主要问题是 只要我不重新初始化 新字节 作为参数传递的数组 这总是有效吗 static unsafe decimal GetDecimal byte ba decimal decimal PTR fixed byte byte PT
  • 在VBA中使用for循环调用连续的变量名(即car1,car2...car10)

    设想 我有七个变量 labelKid1 labelKid2 LabelKid3 我正在搜索单元格以查找不为空的单元格 然后将值输入到标签中 从 labelKid1 开始 然后转到下一个标签 问题 有没有办法让我们使用 for 循环来遍历这些
  • 错误:表达式不可赋值三元运算符

    我有以下代码 MPLABX XC8 编译器给出此错误 错误 表达式不可分配 U1ERRIRbits RXFOIF uart1 oerr 1 uart1 oerr 0 这是相关代码部分 typedef union struct bool fe
  • 将 []string 传递给需要可变参数的函数

    为了不一遍又一遍地重复我的自我 我想创建一个处理运行一些命令的函数 func runCommand name string arg string error cmd exec Command name arg if err cmd Run
  • 无法封送,(实现encoding.BinaryMarshaler)。具有多个对象的 go-redis Sdd

    我有下面一段代码 我试图将一个数组添加到 redis 集中 但它给了我一个错误 package main import encoding json fmt github com go redis redis type Info struct
  • 如何使用 golang 和 mgo 库在 mongodb 中创建文本索引?

    我正在尝试对集合进行全文搜索 但为了做到这一点 我需要创建一个文本索引 http docs mongodb org manual tutorial create text index on multiple fields http docs
  • 指向函数中结构体数组的指针

    我的指针有问题 我想用一个函数读取一个二进制文件 然后在 main c 文件中使用读取的数据 问题是我必须传递一个指向结构数组的指针才能使用 main 中的数据 代码是 define TMOLDEO 8 define TAM 41 stru
  • 使用 for 循环创建链表

    这是我的结构 struct ListItem int data struct ListItem next 假设链表的第一个节点的 data 0 我想编写一个 for 循环来创建大小为 5 的链表 但我不知道如何工作 我尝试了以下方法 int
  • 用 R 计算月回报

    这可能是一个微不足道的问题 但不幸的是我无法解决它 我有 50 家公司的股票投资组合 我有每家公司当天的日期和收盘价 每家公司的数据因股票交易日期而异 我使用以下代码来计算每日收益 return matrix NA nrow compani
  • 优化 golang 中的数据结构/字对齐填充

    与我在 C 中学到的类似 我相信填充导致了两个结构体实例大小的差异 type Foo struct w byte 1 byte x byte 1 byte y uint64 8 bytes type Bar struct x byte 1
  • 将 3 维 numpy 数组传递给 C

    为了提高速度 我正在为我的 Python 程序编写一个 C 扩展 并在尝试传入 3 维 numpy 数组时遇到一些非常奇怪的行为 它适用于二维数组 但我确信我用指针搞砸了一些东西 试图让它适用于第三维 但这是奇怪的部分 如果我只传入一个 3
  • Golang Appengine 项目无法构建

    我有一个使用 golang 的应用程序引擎项目 我已经大约一年没有碰过了 我现在无法让它在之前构建的机器上构建 我收到以下错误 go app builder 解析输入失败 解析器 src golang org x net internal
  • 如何在没有循环的情况下初始化哈希中的值?

    我正在尝试找出一种无需经过循环即可初始化哈希的方法 我希望使用切片来实现这一点 但它似乎没有产生预期的结果 考虑以下代码 usr bin perl use Data Dumper my hash hash currency symbol B
  • GO并发编程测试

    我试图确保我的并发程序不存在以下情况 僵局 livelock 饥饿 我找到了以下工具http blog golang org race detector http blog golang org race detector 我尝试编译并运行
  • 如何在 Goji (Golang) 中使用不同的中间件创建单独的路由组?

    我正在使用Goji https github com zenazn goji https github com zenazn goji 并希望定义具有自己的中间件的路由组 例如 下面的所有路径 company应使用 LDAP 身份验证并定义
  • 共享来自单独命令/进程的属性

    我提供带有多个命令和子命令的命令行工具 我使用cobra https github com spf13 cobra命令行 我有两个单独的命令首先是前提条件e 给其他人 例如第一个命令是通过创建临时文件夹并验证某些文件来首选环境 第二个命令应
  • 为什么for循环只显示最后一个循环的结果

    我有这个样本矩阵 X1 X2 X3 X4 1 F F F F 2 C C C C 3 D D D D 4 A A A A 我正在尝试使用 for 循环来获取每列中唯一音高的数量 我正在尝试这样做 y lt read csv file fra

随机推荐

  • 压缩图像的最佳方法 Javascript React Web App

    我正在寻找最佳的解决方案来压缩我收到并需要存储在数据库中的图像 实际上 我将图像转换为base64 然后将其发送到服务器 handleImage e gt e preventDefault let reader new FileReader
  • 带有准备好的语句的 PostgreSQL 内部查询

    我有一个表来存储联系人 我想获取添加 user id 为 some number 的列的最大值 并将其设置为当前插入记录的相同列值 我正在使用准备好的语句 pg prepare db add INSERT INTO CONTACTS c u
  • 重置 FactoryGirl 测试的“序列”

    有谁知道如何重置FactoryGirl的序列方法 我有一个创建任务列表的工厂 我希望每次都从 1 开始 我使用 序列 是因为任务列表是一个关联模型 所以每次使用时我都需要增加顺序FactoryGirl create直到我调用重置 你需要写F
  • 在 Javascript 中检测 MS Surface 虚拟键盘

    有没有办法通过 Javascript 检测 MS Surface 的虚拟键盘何时显示在网页中 虚拟键盘覆盖了页面上的活动文本字段 我需要能够检测到这一点 以便我可以重新布局页面以更好地使用剩余的窗口区域 None
  • 仅通过单击节点图像来展开/折叠 TreeView

    我的表单上有一个包含大量项目 节点的 TreeView 当我双击节点的项目时 我运行一个过程 取决于单击的项目 我的问题是 我希望它仅在单击节点的图标 或 号 时展开 折叠 如果我双击一个项目则不会 类似的问题 http www delph
  • Ant构建执行cordova

    我为我的 cordova 项目创建了一个 ant 构建 如下所示
  • 如何使用 datafactory 管道转换 xml 数据

    我们如何将 XML 负载中的数据保存到 Blob 存储中 input
  • 对于 Jenkins git 插件,建议在哪里运行 git config ?

    在詹金斯的领导下我也有同样的情况longpaths中描述的问题这个线程 https stackoverflow com questions 22575662 filename too long in git for windows This
  • R Markdown 版本的 \framesubtitle?

    以下是我所知道的创建带有字幕的投影仪幻灯片的最少 TeXy 方法 output beamer presentation Title of Slide framesubtitle Subtitle of Slide Frame content
  • C++ 虚拟继承内存布局

    虚拟继承内存布局 我试图完全理解虚拟继承和 vTables vPtrs 的内存幕后发生的事情以及不发生的事情 我有两个我编写的代码示例 我确切地理解它们工作的原因 但我只是想确保我心中对对象内存布局有正确的想法 Here http post
  • golang递归地反映字段类型和值

    在golang中 我想通过结构体递归地反映 获取字段的名称 类型和值 这里的代码帮助我反思golang递归反射 https stackoverflow com questions 47624318 golang recurisive ref
  • 乘以概率矩阵,大量迭代时出现错误值

    我有下一个代码 它乘以概率矩阵 p一定次数 对于前 50 次迭代 一切正常 每行的概率之和等于1 但后来我收到了sum gt 1大约在第 70 次迭代时 我收到无穷大的值 我不明白为什么 The sum每行的概率必须等于1 这就是经典马尔可
  • PyCharm 显示有效代码的未解析引用错误

    我正在使用 PyCharm 来处理一个项目 项目用解释器打开并配置 可以成功运行 远程解释器路径已正确映射 这似乎是正确的配置 但 PyCharm 突出显示了我的有效代码 其中包含 未解析的引用 错误 即使对于内置 Python 函数也是如
  • 当使用 CPPFLAGS 指定目录时./configure 无法找到头文件

    我正在尝试在 Mac OS X Mavericks 上构建 php gettext 模块 安装了 gettextbrew install gettext 并且已检查的头文件可在 usr local opt gettext ls usr lo
  • 启动容器进程导致“exec:\”/ app \“:权限被拒绝”:未知

    当我尝试使用 docker 构建 golang 时 docker的镜像构建成功 但是使用docker run运行时出现如下错误 docker Error response from daemon OCI runtime create fai
  • Pandas 从分组数据帧计算连续相等值的长度

    我想做他们在答案中所做的事情 pandas中以向量化方式计算特定连续相等值的数量 https stackoverflow com questions 29142487 calculating the number of specific c
  • 气流日志文件异常

    我正在使用 apache airflow 来运行我的 dags 我收到一个异常 Log file does not exist opt airflow logs download2 download2 2020 07 26T15 00 00
  • Delphi 中检测目录是否为连接点

    我一直在谷歌搜索这个 我可能有一些大脑云 因为它不起作用 我需要检测文件夹是否是连接点 以便我的递归文件搜索不会陷入无限循环 我可以使用一个简单的函数 例如 IsJunction attr dword boolean 其中 attr 是dw
  • Chrome 中的“操作码 -1”是什么意思?

    我正在使用 Chrome 浏览器 并且尝试创建 WebSocket 连接 使用 javascript 但有时会出现错误 当我在开发人员工具中查找 WS 连接时 我看到 OPCODE 1 这是什么意思 WebSocket 操作码描述了如何解释
  • 如果对象位于切片中,方法不会更改对象的值

    这是我的程序 package main import fmt type Number struct val int func num Number Increment num val 1 func num Number Value int