Go中funcappend的实现在哪里?

2024-05-05

我对 go 非常感兴趣,并尝试阅读 go 函数的实现。我发现其中一些函数没有实现。

如追加或调用:

// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
//  slice = append(slice, elem1, elem2)
//  slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
//  slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type

// call calls fn with a copy of the n argument bytes pointed at by arg.
// After fn returns, reflectcall copies n-retoffset result bytes
// back into arg+retoffset before returning. If copying result bytes back,
// the caller must pass the argument frame type as argtype, so that
// call can execute appropriate write barriers during the copy.
func call(argtype *rtype, fn, arg unsafe.Pointer, n uint32, retoffset uint32)

看起来不是调用C代码,因为使用cgo需要一些特殊的注释。 这些函数的实现在哪里?


您正在阅读和引用的代码只是具有一致文档的虚拟代码。内置函数内置于语言中,因此包含在代码处理步骤(编译器)中。

简化后发生的情况是:词法分析器将检测到 'append(...)' as APPEND令牌,解析器将翻译APPEND,根据编码的情况/参数/环境,将代码编写为汇编并进行汇编。中间步骤——实施append- 可以在编译器中找到here https://github.com/golang/go/blob/6327e8dc69c47d6355e2623cc491f0140d2563f5/src/cmd/compile/internal/gc/cgen.go#L2748.

会发生什么append当查看示例程序的汇编时,可以最好地看到调用。考虑一下:

b := []byte{'a'}
b = append(b, 'b')
println(string(b), cap(b))

运行它将产生以下输出:

ab 2

The append调用被转换为汇编,如下所示:

// create new slice object
MOVQ    BX, "".b+120(SP)       // BX contains data addr., write to b.addr
MOVQ    BX, CX                 // store addr. in CX
MOVQ    AX, "".b+128(SP)       // AX contains len(b) == 1, write to b.len
MOVQ    DI, "".b+136(SP)       // DI contains cap(b) == 1, write to b.cap
MOVQ    AX, BX                 // BX now contains len(b)
INCQ    BX                     // BX++
CMPQ    BX, DI                 // compare new length (2) with cap (1)
JHI $1, 225                    // jump to grow code if len > cap
...
LEAQ    (CX)(AX*1), BX         // load address of newly allocated slice entry
MOVB    $98, (BX)              // write 'b' to loaded address

// grow code, call runtime.growslice(t *slicetype, old slice, cap int)
LEAQ    type.[]uint8(SB), BP
MOVQ    BP, (SP)               // load parameters onto stack
MOVQ    CX, 8(SP)
MOVQ    AX, 16(SP)
MOVQ    SI, 24(SP)
MOVQ    BX, 32(SP)
PCDATA  $0, $0
CALL    runtime.growslice(SB)  // call
MOVQ    40(SP), DI
MOVQ    48(SP), R8
MOVQ    56(SP), SI
MOVQ    R8, AX
INCQ    R8
MOVQ    DI, CX
JMP 108                        // jump back, growing done

正如你所看到的,没有CALL调用函数的语句append看得到。这是全面落实append调用示例代码。使用不同参数的另一个调用will看起来不同(其他寄存器,不同的参数取决于切片类型等)。

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

Go中funcappend的实现在哪里? 的相关文章

随机推荐

  • 如何为十六进制颜色字符串创建独立类型?

    我正在尝试在 TypeScript 中创建一个独立类型 可用于将单个有效的十六进制颜色代码表示为完全类型安全的字符串 我的尝试如下 但由于实际上不是独立类型而未能实现 而这正是我希望实现的目标 type HexDigit
  • 何时使用支持库

    我对 Android 支持库的用途和何时需要它感到困惑 据我了解 使用支持库的主要优点是 Android 可以在旧版本中自行实现主题和 UI 功能 而无需开发人员显式定义它们 这些关键的 UI 功能之一是操作栏 它是为 Honeycomb
  • SaveState/LoadState 之后无法设置 MediaElement Source

    注意 所有代码都已被严重简化 Problem 暂停 恢复后未设置 MediaElement 源 设置源后 CurrentState 会快速更改为 Closed 我正在处理 MediaFailed 事件 它不会触发 我还在处理 MediaOp
  • 如何设置评分栏的星星颜色?

    如何设置评分栏的星星颜色 我想要黄色星星 最简单的方法 android progressTint color color 光滑有光泽
  • 在 grid.text 中使用 pch 字符

    我使用 ggplot2 创建了一个图表 现在我想让图例不在图表上 而是在图表外的网格中 我现在的问题是 是否有人知道是否有可能在 grid text 中使用 pch 符号 Here is an image to show what I wa
  • WSO2 ESB 4.0.3 - 从 4.0.* 存储库安装数据服务功能时出错

    我下载了 WSO2 ESB 4 0 3 并将其解压到我的 MAC OSX 10 7 5 的 MAC book PRO 上 我通过管理 UI 添加了以下存储库 http dist wso2 org p2 carbon releases 4 0
  • 为什么在二维数组中 a 和 *a 指向相同的地址? [复制]

    这个问题在这里已经有答案了 我只是想了解二维数组是如何实现的以及内存分配是如何发生的 所以我对给定的 c 程序有些疑问 为什么 a 和 a 给出相同的地址 include
  • 将两个相似的远程 git 存储库合并为一个

    我已经做了一些搜索并阅读了 git 书籍和网络上的一些地方 例如 git 但我找不到正确的方法来做到这一点 我有两个 git 存储库 位于两台不同的机器上 这些 git 存储库中的每一个都保存程序的配置 当您比较两个存储库时 配置的某些部分
  • android 表格内的可聚焦行

    我在 xml 中有一个 ScrollView 其中包括一个 TableLayout 我的问题是 每次我单击它时是否可以有一个可聚焦的行 这是我的 xml 代码
  • 有没有办法在两个 Visual Studio 实例之间拖放来复制文件?

    有没有办法在两个 Visual Studio 2008 实例之间复制文件 插件 设置还是其他什么 目前 将文件从一个实例拖动到另一个实例不会执行任何操作 鼠标显示该操作无效 右键单击文件并从实例 1 中选择 复制 然后粘贴到实例 2 中会导
  • 如何匹配特质实现者

    我有一个由某些结构实现的特征 我想编写一个模式匹配 可以处理每种可能的情况 trait Base struct Foo x u32 struct Bar y u32 impl Base for Foo impl Base for Bar f
  • 在 GitHub 上托管可执行文件?

    我想将可执行文件与我的源代码一起分发 我的源代码全部整齐地托管在 GitHub 上 是否可以将可执行文件和安装程序添加到我的 GitHub 项目页面 而不将它们添加到我的 git 存储库 请注意 由于某种原因 GitHub 停止了此功能 请
  • 如何使用 Spark 执行插入覆盖?

    我正在尝试将我们的 ETL Hive 脚本之一转换为 Spark 其中 Hive ETL 脚本维护一个表 其中需要在每晚新同步之前删除部分数据 Hive ETL 使用插入覆盖的方式将主表删除超过 3 天的数据 基本上创建一个临时表 其中的数
  • 支持多屏幕[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 支持多个屏幕和不同的屏幕密度必须注意
  • 计算集合中某种类型的对象并将其用作文本框中的字符串

    我想用集合中某种图形的 count 1 填充文本框 该集合是图形的通用列表 图形是某种类型的图形的实例 以下作品 txtName Text figures OfType
  • 为什么 LocationSettingsResult startResolutionForResult 不调用 onActivityResult?

    我看过这个问答LocationSettingsRequest 对话框 跳过 onActivityResult https stackoverflow com questions 31235564 locationsettingsreques
  • SharePoint DateTime 默认值尊重时区

    我有一个日期时间字段 仅限日期 它使用 今天的日期 作为默认值 但是 当用户将项目添加到列表时 选择的日期对应于 GMT 时区 因此 如果用户在 2012 年 2 月 22 日晚上 7 点 美国东部标准时间 添加项目 则默认值实际上将显示为
  • 修改rails ActiveAdmin gem中的BaseController

    我在 Rails 应用程序中使用 ActiveAdmin gem 如果我想添加一个适用于所有 activeadmin gem 的新的 before 过滤器 我该怎么做 我想我可以修改 ActiveAdmin 中的 BaseControlle
  • 如何在 django-tastypie 中获取授权用户对象

    我需要在水合物方法中获取授权用户对象 如下所示 class SalepointResource ModelResource def hydrate self bundle user bundle request user But reque
  • Go中funcappend的实现在哪里?

    我对 go 非常感兴趣 并尝试阅读 go 函数的实现 我发现其中一些函数没有实现 如追加或调用 The append built in function appends elements to the end of a slice If i