切片如何包含自身?

2023-12-26

我正在尝试使用“The Go 编程语言”来学习 Golang,并且我已经到达了关于切片的部分。它们在数组和切片之间进行比较,因为两个数组可以与==其中两片不能。正文如下:

"== operator for arrays of strings, it may be puzzling that slice
comparisons do not also work this way. There are two reasons why deep 
equivalence is problematic. First, unlike array elements, the elements
of a slice are indirect, making it possible for a slice to contain 
itself. Although there are ways to deal with such cases, none is 
simple, efficient, and most importantly, obvious."

由于元素是间接的,切片可能包含自身是什么意思?


包含自身的切片

除了递归类型(例如type Foo []Foo,请参阅 ANisus 的答案),除了演示之外没有任何用处,如果切片的元素类型是,则切片可能包含自身interface{}:

s := []interface{}{"one", nil}
s[1] = s

在此示例中,切片s将有 2 个接口值,第一个“包装”一个简单的字符串"one",以及包装切片值本身的另一个接口值。创建接口值时,将包装该值的副本,在切片的情况下,这意味着切片标头/描述符的副本,其中包含指向底层数组的指针,因此该副本将具有指向的相同指针值相同的底层数组。 (有关接口表示的更多详细信息,请参见反射定律:接口的表示 http://blog.golang.org/laws-of-reflection#TOC_3..)

如果您很快就开始打印它:

fmt.Println(s)

你会得到一个致命错误,比如:

runtime: goroutine stack exceeds 250000000-byte limit
fatal error: stack overflow

Because fmt.Println()尝试递归地打印内容,并且由于第二个元素是一个切片,指向正在打印的切片的同一数组,因此它会陷入无限循环。

另一种查看它是否真的是切片本身的方法:

s := []interface{}{"one", nil}
s[1] = s
fmt.Println(s[0])

s2 := s[1].([]interface{})
fmt.Println(s2[0])

s3 := s2[1].([]interface{})
fmt.Println(s3[0])

输出(尝试一下去游乐场 http://play.golang.org/p/Uj191SWibK):

one
one
one

无论我们走多深,第二个元素始终是指向同一个数组的切片值s,包裹在interface{} value.

间接寻址起着重要作用,因为副本将被包装在interface{}但副本将包含相同的指针。

数组不能包含自身

将类型更改为数组:

s := [2]interface{}{"one", nil}
s[1] = s
fmt.Println(s[0])

s2 := s[1].([2]interface{})
fmt.Println(s2[0])

s3 := s2[1].([2]interface{})
fmt.Println(s3[0])

输出(尝试一下去游乐场 http://play.golang.org/p/yz71cZ_bSF):

one
one
panic: interface conversion: interface is nil, not [2]interface {}

这是因为当数组被包装成interface{},副本将被包装 - 并且副本不是原始数组。所以s将有第二个值,interface{}包装一个数组,但这是一个不同的数组,其第二个值未设置,因此将是nil(类型的零值interface{}),因此尝试“进入”这个数组将会出现恐慌,因为它是nil (类型断言 https://golang.org/ref/spec#Type_assertions失败是因为没有使用特殊的“逗号,ok”形式)。

从此s数组不包含自身,一个简单的fmt.Println()将揭示其完整内容:

fmt.Println(s)

Output:

[one [one <nil>]]

Further interface{}包裹分析

如果将数组包装在interface{}并修改原始数组的内容,包装在interface{}不受影响:

arr := [2]int{1, 2}
var f interface{} = arr
arr[0] = 11

fmt.Println("Original array:    ", arr)
fmt.Println("Array in interface:", f)

Output:

Original array:     [11 2]
Array in interface: [1 2]

如果对切片执行相同的操作,则包装的切片(因为指向相同的底层数组)也会受到影响:

s := []int{1, 2}
f = s
s[0] = 11

fmt.Println("Original slice:    ", s)
fmt.Println("Slice in interface:", f)

Output:

Original slice:     [11 2]
Slice in interface: [11 2]

尝试这些去游乐场 http://play.golang.org/p/KrQQDkVXNf.

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

切片如何包含自身? 的相关文章

  • 使用 numpy 在 python 中执行最大方差旋转

    我正在研究矩阵的主成分分析 我已经找到了如下所示的组件矩阵 A np array 0 73465832 0 24819766 0 32045055 0 3728976 0 58628043 0 63433607 0 72617152 0 5
  • 数组索引超出范围的表视图

    我正在使用数组从数据库读取数据 目前数组中有 8 个项目 我正在尝试制作一个有节标题的表格 目前我有 4 个部分 并且我已正确设置并且它有效 它也可以在第一次运行时运行 但是当我尝试向后滚动时 我发现索引超出了范围 我正在使用 myarra
  • Javascript 无法正确排序 DECIMAL 数字

    我有一些代码可以按字母顺序对名称进行排序 我遇到的问题是它处理小数的方式 它对名称进行排序 如下所示 我宁愿它按数字递增 DOG 1 0510 DOG 1 1031 DOG 11 1792 DOG 12 0920 DOG 12 1170 D
  • Javascript - 使数组索引 toLowerCase() 不起作用

    我试图将所有数组索引设置为小写字符串 但它不起作用 我在这里查看了其他答案并尝试了他们的解决方案 例如使用toString 添加之前toLowerCase但它不起作用 这很奇怪 我创建了一个问题的jsfiddlehere https jsf
  • 如何从对象数组中删除所有重复项?

    This is a large array of objects e g let totalArray id rec01dTDP9T4ZtHL4 fields user id 170180717 user name abcdefg even
  • 竞争性编码 - 以最低成本清除所有级别:未通过所有测试用例

    当我遇到这个问题时 我正在一个竞争性编码网站上解决问题 问题指出 游戏中有 N 个关卡和 M 种可用武器 等级编号从 0 到 N 1 武器编号从 0 到 M 1 您可以按任意顺序清除这些级别 在每个关卡中 需要这些 M 武器的某些子集才能通
  • 如何初始化一个大多数值相同但某些值不同的静态数组?

    我想使用静态或常量数组 但使用除 T N 句法 我需要定义特定元素 但所有其他值都可以默认为 0 或其他值 在 C 中 您可以执行以下操作 byte ARRAY 256 0x1F 1 lt lt 4 Or even simply just
  • 向用户显示多条验证消息

    在 MS Access 中 如何将从 SELECT 语句检索到的行存储在数组中 并在一个消息框中显示多行 Dim rSEL rSUM rDes As DAO Recordset Dim vItem id vQnty vSum As Inte
  • 为关联数组选择哪种映射类型?学说ODM

    我有一个关于 顺便说一句 真的很棒 Doctrine ODM 的简单问题 假设您有一个类似以下的文档 Document class Test Id public id WHICHTYPE public field array 现在我想存储一
  • 在php中对带有特殊字符的多维数组进行排序

    我有一个多维数组 我按字母顺序排序 但问题是 带有丹麦语特殊字符 它们应该按该顺序排序 但不会按该顺序返回 这是我的数组 部分已删除 Array 0 gt Array Name gt John 1 gt Array Name gt Pate
  • 是否保证 sizeof(T[N]) == N * sizeof(T) ?

    我一直假设 N 个元素类型的数组的大小T 由返回sizeof保证正好是N次sizeof T The 对这个问题的评论 https stackoverflow com questions 46457449 is it always the c
  • 对数字和字母元素的数组进行排序(自然排序)

    假设我有一个数组 var arr 1 5 ahsldk 10 55 3 2 7 8 1 2 75 abc huds 我尝试对其进行排序 我得到了类似的东西 1 1 10 2 2 3 5 55 7 75 8 abc ahsldk huds 注
  • Golang:如何在HTTP客户端的TLS配置中指定证书

    我有一个证书文件 该位置是 usr abc my crt我想将该证书用于我的 tls 配置 以便我的 http 客户端在与其他服务器通信时使用该证书 我当前的代码如下 mTLSConfig tls Config CipherSuites u
  • Powershell 数组到带引号的逗号分隔字符串

    我有一个数组 需要输出到逗号分隔的字符串 但我还需要引号 这是我所拥有的 myArray file1 csv file2 csv a myArray join a 输出为 a最终 file1 csv file2 csv 我想要的输出是 fi
  • 打印 Java 数组的最简单方法是什么?

    在 Java 中 数组不会覆盖toString 所以如果你尝试直接打印一个 你会得到className 的十六进制hashCode https en wikipedia org wiki Java hashCode 数组的定义为Object
  • 获取 Nd4j 数组的任意切片

    我想以与使用 Numpy 相同的方式在任意大小的 Nd4j 中执行切片 a numpy arange 100 a 25 50 nd4j slice 方法仅接受维度和索引参数 而不接受长度 我怎样才能实现这个目标 我知道这是一个老问题 但我在
  • 当名称是数组时如何使用 Javascript 修改 HTML Select

    我有两个同名的 html select 对象 它们是具有不同索引的数组 我想做的是 如果从类别 0 选择元素中选择 关闭 我想禁用类别 1 元素 我一直在尝试使用 document getElementsByName 但无法弄清楚如何专门针
  • []interface{}{} 中的双大括号是什么意思

    请注意 这是格式为 的双花括号 而不是嵌套花括号 我也不确定这是空接口问题 切片问题还是结构问题 我猜它至少是其中两个的组合 我正在学习 Golang 并且已经达到了空接口 我发现我需要将空接口声明为 interface 或者例如 inte
  • 如何 grep 遍历数组,同时过滤掉匹配项?

    有没有一种快速简便的方法来 grep 遍历数组 找到满足某些测试的元素and从原始数组中删除这些 例如我想要 a 1 7 6 3 8 4 b grep filter gt 5 a now b 7 6 8 and a 1 3 4 换句话说 我
  • 从java中的字符串数组中删除空值

    java中如何从字符串数组中删除空值 String firstArray test1 test2 test4 我需要像这样没有 null 空 值的 firstArray String firstArray test1 test2 test4

随机推荐

  • ODEi​​nt:任意精度的自适应积分

    ODEi nt 是否可以使用adaptive具有任意精度算术的积分例程 例如 我想将 Boost 多精度库与集成自适应 函数和受控步进器一起使用 ODEi nt 文档提供了对integrat const 使用任意精度算术的示例 但我无法修改
  • Windows Phone 8.1 上使用 .resx 资源时出现 MissingManifestResourceException

    我正在开发一个也针对 Android Xamarin 的 Windows Phone 8 1 应用程序 正如我在 PCL 上添加字符串资源 resx 并在启动器项目中引用它们以在我的视图中使用它一样 这一切在 WP 8 1 silverli
  • MySQL 中的字符串连接

    我正在使用 MySQL 和 MySQL Workbench 5 2 CE 当我尝试连接两列时 last name and first name 它不起作用 select first name last name as Name from t
  • + 运算符什么时候比 StringBuilder 更快? [复制]

    这个问题在这里已经有答案了 过去 我一直相信你应该使用StringBuilder and append String 当用变量构建字符串时 而不是string split i 在什么情况下这是准确的 我问是因为通常情况下 如果我要写以下内容
  • 直接从无窗口 Linux 终端启动 OpenGL 应用程序

    究竟如何让 OpenGL 应用程序直接从终端 Ubuntu Server 9 04 全屏运行 我在我的服务器上开发了一个用于视觉诊断的应用程序 但是 我不完全确定让它在无窗口环境中运行的最佳方法 理想情况下 我会运行我的程序 visuald
  • 在 TFS 中的解决方案之间共享代码 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我有几个不同的应用程序 我需要在它们之间共享代码以减少维护 我尝试在 stackoverflow 和 web 上阅读大量
  • 提取两个字符串之间不同的字符

    我用过adist计算两个字符串之间不同的字符数 a lt Happy day b lt Tappy Pay adist a b result 2 现在我想提取那些不同的字符 在我的示例中 我想获取字符串 Hd or TP 没关系 我试着看一
  • 通过 Gmail 发送电子邮件时出现错误

    在这里 我尝试使用 gmail 发送邮件 但出现以下错误 javax mail AuthenticationFailedException 534 5 7 14
  • 在 Laravel 4 中显示自定义验证的错误消息

    我通过创建一个类创建了一个自定义错误函数
  • 未定义参数的性能损失

    我经常在函数中使用可选参数 但一些测试显示它们在 Firefox 和 safari 中性能受到巨大影响 70 95 奇怪的是 如果我传入文字值不明确的那么就没有处罚 这里可能发生什么 我不会认为这是一个作用域链问题 因为它们本质上是函数的本
  • 正则表达式也匹配重音字符

    我有以下 PHP 代码 search foo bar que search string str replace search text This is my foo text with qu and other accented char
  • 如何以只读方式打开 Eclipse 项目?

    有谁知道有没有办法在 Eclipse 中以只读模式打开项目 如果打开了很多类似的项目 很容易对错误的项目进行更改 当您从前一个项目创建另一个实例时 将项目置于只读模式非常有用 因此 您复制旧项目中的所有文件 然后在新实例中进行更改 错误地编
  • Primefaces 数据表的列标题中的工具提示

    在基于的应用程序中JSF 2 1 and Primefaces 6 0 我正在尝试向数据表的标题添加工具提示 在我当前的解决方案中 仅当将鼠标精确指向文本标题 Projekttyp 时才会出现工具提示 我需要每当鼠标指针位于列标题中时就显示
  • 使用 jQuery 和 iFrame 下载大文件 - 需要文件就绪事件,以便我可以隐藏加载 gif

    我正在使用 jQuery 下载一些需要一些时间才能创建的文件 因此我显示了一个加载 gif 来告诉用户要有耐心 但问题是 加载 gif 当前显示和隐藏都在一瞬间 有没有办法让我在下载完成后隐藏加载 gif 并且用户在屏幕上弹出 保存文件 窗
  • Vaadin 为版本控制添加什么

    我们正在使用 Vaadin 14 我们应该将项目中的哪些文件夹提交到版本控制 文件夹node modules非常大 非常耗时 我们应该提交这个吗 node modules目录不应该加入版本控制 package json and packag
  • 通过 Facebook 的图 api 发布状态

    在 PHP 中 我尝试使用图形 api 将状态发布到我们的 Facebook 粉丝页面 尽管遵循 facebook 给出的说明 但以下代码似乎没有更新状态 这是代码 xPost access token key xPost message
  • Android:如何通过xml制作看起来像光环的Circle

    我正在尝试使用带有光环的 xml 制作一个圆圈 光环就像从中心的绿色开始 绿色不断褪色 最后在边缘变得透明 该怎么办呢 我正在尝试使用以下内容
  • 如何在限制 ssh 的防火墙后面通过 https 访问 heroku git

    Heroku 部署在我家里就像一个魅力 但我的办公室网络限制 ssh 这会阻止命令 git push heroku master 有没有办法使用 heroku git 存储库的 https url 来推送我的应用程序 您只能通过 ssh 推
  • @IdClass JPA 注解

    这是我的一个实体的复合主键 public class GroupMembershipPK implements Serializable private static final long serialVersionUID 78164338
  • 切片如何包含自身?

    我正在尝试使用 The Go 编程语言 来学习 Golang 并且我已经到达了关于切片的部分 它们在数组和切片之间进行比较 因为两个数组可以与 其中两片不能 正文如下 operator for arrays of strings it ma