草庐IT

pointers - 附加到其他 slice 内的结构上的 slice 不持久

coder 2024-07-11 原文

例如:

package main

import "fmt"

type Test struct {
  elems []string
}

func main() {
  initial := Test{
    elems: make([]string, 0),
  }
  initial.elems = append(initial.elems, "apple")
  fmt.Println(initial.elems) // #1 [apple]

  s := make([]Test, 0)
  s = append(s, initial)

  initial.elems = append(initial.elems, "bannana")
  fmt.Println(initial.elems) // #2 [apple bannana]
  fmt.Println(s[0].elems) // #3 [apple]

  second := s[0]
  second.elems = append(second.elems, "carrot")
  fmt.Println(second.elems) // #4 [apple bannana]
}

我正在寻求帮助来理解打印语句 #3 和 #4。在 #3 中,我期望 [apple bannana],在 #4 中,我期望 [apple bannana carrot]

据我了解,作为 slice 的 elems 字段会自动通过引用传递,因此我在上面的代码块中所做的每个追加都应该修改底层数组。但是,显然情况并非如此。

所以,我的问题是:当 initial 被插入到一个 slice 中时会发生什么,导致它不起作用?此外,如何编写此代码才能在打印语句 #4 处获得预期结果?

最佳答案

在 Golang 中提到:

Map and slice values behave like pointers: they are descriptors that contain pointers to the underlying map or slice data. Copying a map or slice value doesn't copy the data it points to.

附加到 slice s 的方式是通过将 Test 结构的副本添加到 s slice 来创建一个新 slice 。因此,您没有设置指向原始 Test 结构的指针。因此,如果结构内部的数据发生变化,它也会反射(reflect)在 slice 中。这就是您面临的问题。

  initial.elems = append(initial.elems, "apple")
  fmt.Println(initial.elems) // #1 [apple]

  s := make([]Test, 0) // this should be pointer to the struct to have teh changes in future to original struct.
  s = append(s, initial) // appending to the s slice

在制作 slice s 时创建一个指向 Test 结构的指针,每当您更改原始结构中的元素时,它将反射(reflect)更改。例如:

package main
import "fmt"

type Test struct {
  elems []string
}

func main() {
  initial := Test{
    elems: make([]string, 0),
  }
  initial.elems = append(initial.elems, "apple")
  fmt.Println(initial.elems) // #1 [apple]

  s := make([]*Test, 0) // create a pointer to Test struct.
  s = append(s, &initial)

  initial.elems = append(initial.elems, "bannana")
  fmt.Println(initial.elems) // #2 [apple bannana]
  fmt.Printf("%+v\n",*s[0]) // #3 [apple banana]

  second := s[0]
  second.elems = append(second.elems, "carrot")
  fmt.Println(second.elems) // #4 [apple bannana carrot]
}

输出:-

[apple]
[apple bannana]
{elems:[apple bannana]}
[apple bannana carrot]

关于 Go Playground 的工作代码

关于pointers - 附加到其他 slice 内的结构上的 slice 不持久,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52823467/

有关pointers - 附加到其他 slice 内的结构上的 slice 不持久的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  5. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  6. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  7. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  8. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  9. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  10. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

随机推荐