在 Go 函数中返回本地数组的切片安全吗?

2024-04-06

如果我返回作为函数或方法的局部变量的数组切片,会发生什么情况? Go 是否将数组数据复制到创建的切片中make()?容量与切片大小或数组大小匹配吗?

func foo() []uint64 {
    var tmp [100]uint64
    end := 0
    ...
    for ... {
        ...
        tmp[end] = uint64(...)
        end++
        ...
    }
    ... 
    return tmp[:end]
} 

这在规格:切片表达式 https://golang.org/ref/spec#Slice_expressions.

该数组不会被复制,但切片表达式的结果将是引用该数组的切片。在 Go 中,从函数或方法返回局部变量或其地址是完全安全的,Go 编译器执行逃逸分析 https://en.wikipedia.org/wiki/Escape_analysis确定一个值是否可以逃逸该函数,如果可以(或者更确切地说,如果它不能证明一个值不能逃逸),它将在堆上分配它,以便在函数返回后可用。

切片表达式:tmp[:end] means tmp[0:end](因为缺少一个low索引默认为零)。由于您没有指定容量,因此默认为len(tmp) - 0这是len(tmp)这是100.

您还可以通过使用控制结果切片的容量全切片表达式,其形式为:

a[low : high : max]

这将结果切片的容量设置为max - low.

更多示例来阐明生成的切片的长度和容量:

var a [100]int

s := a[:]
fmt.Println(len(s), cap(s)) // 100 100
s = a[:50]
fmt.Println(len(s), cap(s)) // 50 100
s = a[10:50]
fmt.Println(len(s), cap(s)) // 40 90
s = a[10:]
fmt.Println(len(s), cap(s)) // 90 90

s = a[0:50:70]
fmt.Println(len(s), cap(s)) // 50 70
s = a[10:50:70]
fmt.Println(len(s), cap(s)) // 40 60
s = a[:50:70]
fmt.Println(len(s), cap(s)) // 50 70

尝试一下去游乐场 https://play.golang.org/p/ECJck-Px0p.

避免堆分配

如果您想在堆栈上分配它,则不能返回任何指向它(或其部分)的值。如果将其分配在堆栈上,则无法保证返回后它仍然可用。

一个可能的解决方案是将一个指向数组的指针作为函数的参数传递(并且您可以返回一个指定useful函数填充的部分),例如:

func foo(tmp *[100]uint64) []uint64 {
    // ...
    return tmp[:end]
}

如果调用者函数创建数组(在堆栈上),这不会导致“重新分配”或“移动”到堆:

func main() {
    var tmp [100]uint64
    foo(&tmp)
}

Running go run -gcflags '-m -l' play.go,结果是:

./play.go:8: leaking param: tmp to result ~r1 level=0
./play.go:5: main &tmp does not escape

变量tmp没有移动到堆。

注意[100]uint64被认为是要在堆栈上分配的小数组。详情请参阅关于堆栈分配,Go 中什么被视为“小”对象? https://stackoverflow.com/questions/42243197/what-is-considered-small-object-in-go-regarding-stack-allocation/42244087#42244087

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

在 Go 函数中返回本地数组的切片安全吗? 的相关文章

  • ruby 中的数组切片返回不同的结果 - nil 与空数组

    我对以下事实感到困惑 如果对数组进行切片length 它返回一个空数组 但长度大于该值时 它返回nil 这是什么原因呢 例如 arr 1 2 3 4 5 这样做 在哪里y gt arr length and x是任意正整数 返回nil ar
  • Java:带有 unicode 字符的 String.toCharArray()

    我知道 char 不能包含 Unicode 字符 例如 char c u1023 那么我该怎么做 String s ABCDEFG u1023 char c s toCharArray 出于性能原因 我想将 s 转换为 CharArray
  • 递归替换多维数组中特定键每次出现的值

    我有一个数组 其数组深度可能会有所不同 例如 array one gt array array something gt value array something2 gt value2 another gt anothervalue tw
  • Android 中的字符串加密

    我正在使用代码进行加密和加密 它没有给出字符串结果 字节数组未转换为字符串 我几乎尝试了所有方法将字节数组转换为字符 但没有给出结果 public class EncryptionTest extends Activity EditText
  • Golang 优雅地关闭 HTTP 服务器并进行错误处理

    我正在让我的 HTTP 服务器正常关闭 我从帖子中获取了提示here https stackoverflow com questions 39320025 how to stop http listenandserve 并且到目前为止已经像
  • 在 Go 中生成随机、固定长度的字节数组

    我有一个字节数组 固定长度为4 token make byte 4 我需要将每个字节设置为随机字节 我怎样才能以最有效的方式做到这一点 这math rand就我而言 方法不提供随机字节函数 也许有一种内置的方法 或者我应该生成一个随机字符串
  • 将数组文字传递给 PostgreSQL 函数

    我有一个包含 select 语句的 Postgres 函数 我需要使用包含字符串值数组的传入变量添加条件 CREATE OR REPLACE FUNCTION get questions vcode text RETURN return v
  • java中初始化并返回一个字节数组

    在我的代码中 我必须将一个 bye 数组 byte temp null 传递给 函数在其内部分配并填充数据 后 从函数返回它仍然为空 我怎样才能找到一个 解决这个问题 请帮我 byte temp null ret foo temp bool
  • 我想在后端验证来自 golang 前端的时区

    前端在注册期间发送时区以及其他用户详细信息 我需要在时区上放置一个验证器来进行 api 测试 时区数据的格式为 GMT 10 00 Hawaii GMT 08 00 Pacific Time US amp Canada 我所做的是定义数组中
  • Go中如何自定义http.Client或http.Transport超时重试?

    我想实现一个自定义http Transport对于标准http Client 如果客户端超时 它将自动重试 附 由于某种原因 习俗http Transport is a 一定有 我已经查过了hashcorp go retryablehttp
  • 将数组数组的字符串转换为 Javascript 数组数组的优雅方法?

    我有一个 ajax 请求 它返回一个值列表 如下所示 5 5 5 6 15 15 7 13 12 我需要它是一个带有数字的 javascript 数组 5 5 5 6 15 15 7 13 12 我尝试将 和 替换为 然后用 分割和 for
  • 如何将数组与 setState 一起使用?

    我目前正在使用以下命令将数组映射到 setState 但没有设置任何内容 也没有记录任何错误 如果我明确地逐行写出它 它就会起作用 关于如何解决这个问题有什么想法或建议吗 使用数组设置状态 不设置状态 const myData messag
  • 当涉及多个渠道时,select 如何工作?

    我发现在多个非缓冲通道上使用 select 时 例如 select case lt chana case lt chanb 即使两个通道都有数据 但在处理此选择时 case chana 和 case chanb 的跟注不平衡 package
  • PHP if in_array 表示多个值

    我有一个由 3 到 12 个值之间的任意位置生成的数组 它根据帐户信息生成该数组 result ad gt user gt groups user username 我想检查这个数组是否有多个值 大约 4 或 5 个 如果其中有任何一个值
  • 在 Go 中跟踪 HTTP 请求时指定超时

    我知道通过执行以下操作来指定 HTTP 请求超时的常用方法 httpClient http Client Timeout time Duration 5 time Second 但是 我似乎不知道在跟踪 HTTP 请求时如何执行相同的操作
  • PHP 中两个关联多维数组的值求和

    我正在尝试对两个关联数组的值求和 这是第一个数组 Array Jan 01 2013 gt Array COM gt 100 RES gt 200 Oct 28 2014 gt Array COM gt 300 RES gt 400 这是第
  • 如何在 Java 中创建要打印到 JFrame 的 JLabels 数组

    我正在尝试制作一系列标签 每个标签都有一个来自函数的不同值 我不知道要使用的标签的确切数量 我的意思是可以打印任意数量的值 请帮我做这件事 很简单 只需一个方法返回一个数组或一些 JLabels 集合 并将它们全部添加到您的 JCompon
  • 如何找到查询结果的大小

    我在 Rails 中有以下查询 records Record select y id source where source gt source y id gt y id group y id source having count 1 如
  • 将 JSON 数组转换为 bash 数组并保留空格

    我想将 JSON 文件转换为 bash 字符串数组 稍后我可以对其进行迭代 我的JSON结构如下 USERID TMCCP CREATED DATE 31 01 2020 17 52 USERID TMCCP CREATED DATE 31
  • 如何解析 Content-Disposition 标头以检索文件名属性?

    使用 go 如何解析从 http HEAD 请求检索到的 Content Disposition 标头以获取文件的文件名 此外 如何从 http HEAD 响应中检索标头本身 这样的事情正确吗 resp err http Head http

随机推荐

  • Html 分页符不起作用

    尝试在我正在处理的页面中设置分页符 但在打印预览中我仍然看到页面上不应该出现的内容 不明白为什么这不起作用 在我的CSS样式中 applicant break hr page break after always 在我的 ASP NET 代
  • Ruby On Rails 和 Ruby 有什么区别? [复制]

    这个问题在这里已经有答案了 可能的重复 Ruby 和 Ruby on Rails 之间有什么区别 https stackoverflow com questions 1237372 what is the difference betwee
  • 自定义 highcharts 工具提示以显示日期时间

    我正在开发一个项目 预计会显示此图 http jsfiddle net Kc23N http jsfiddle net Kc23N 当我单击一个点 工具提示 时 我想显示一个可以理解的日期 而不是以毫秒为单位的值 我认为需要更改这段代码 t
  • 如何以编程方式创建 UIImage 视图 - Swift

    我正在尝试以编程方式创建 UIImage 视图 我有一个新视图 我尝试这样做 let imageName yourImage png yourview backgroundColor UIColor colorWithPatternImag
  • 重叠数据标签折线图高图

    How i can solve the problem of the values dataLabels below 我的 JSFiddle http jsfiddle net 3kVJS 3 http jsfiddle net 3kVJS
  • 如何在 C# Core Console 应用程序中使用 MemoryCache?

    我想在 NET Core 2 0 控制台应用程序中使用 Microsoft Extensions Caching Memory MemoryCache 实际上 在控制台或 asp net 应用程序中使用的库中 我创建了一个测试应用程序 us
  • OpenID,如何开发提供商

    目前我正在开发一些基础设施 并且已经实现了自己的 RESTful 身份验证机制 现在我想也许我不应该走这条路并使用行业标准 因此与我的项目的互操作性在身份验证和授权方面可能很琐碎并且更容易理解 查了一些文章后googling在 Stacko
  • 如何通过 QTest 访问 QMessageBox

    我正在创建一些自动化的图形用户界面测试在我的应用程序中使用QTest 我可以使用以下命令从我的应用程序访问小部件 savePushButton mainWindow gt findChild
  • Ajax + q翻译

    嗨 我遇到了同样的问题里克曾在这里 https stackoverflow com questions 7571643 qtranslate plugin and ajax requests rq 1 给出的答案是他必须 在代码中搜索链接请
  • python 中处理 Excel 文件的最佳库是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个很大的Excel 里面有很多工作表和工作表内相互链接的公式 我需要使用代码在一张纸中填充输入 并
  • NSTableView 排序

    我在 NSTableView 中有两列作为名称和薪水 有 5 10 个值 我想在单击两个列的标题后对这些列进行排序 互联网上有很多数据 但我无法使用这些数据 请帮我在可可中做到这一点 预先感谢并感谢任何帮助 每个表列都有一个方法setSor
  • 由 Javascript 填充的 QML ListView

    我刚刚意识到 根据一些 QML Bugreport ListView 缺少 JSON Delegate 所以我有两个选择 通过用Javascript或C 创建的模型来填充它 特别是我需要从预定义的 URL 下载 json 数据并将它们解析到
  • 如何在高图表中放置自定义标签

    我正在尝试执行官方 HighCharts 小提琴中的操作 http jsfiddle net gh get library pure highcharts highcharts tree master samples highcharts
  • 在 UISearchBar 中自动显示文本光标

    是否可以始终在 UISearchBar 中显示文本光标 不仅在触摸后 add this void viewDidAppear BOOL animated mySearchBar becomeFirstResponder super view
  • 正则表达式解析货币价值

    我需要在 AS3 中编写一个 RegExp 它将 Excel 格式的货币值解析为数字 例如 正则表达式 35 600 00 35600 并检查其格式是否正确 使用 作为千位分隔符 作为小数点 货币符号可以是任何符号 不仅仅是 并且可以位于开
  • 使用 IP 地址而不是域名发送电子邮件

    我试图避免通过 DNS 服务器将电子邮件发送到我托管的虚拟帐户之一上的地址 我知道我可以用方括号将 IP 地址括起来 但如何为服务器上的 虚拟 托管帐户指定邮箱用户名 换句话说 我在虚拟服务器上托管了多个域 所有域共享相同的 IP 地址 明
  • 如何更改列表框中单词的颜色

    我制作了一个带有文本框的表单 它接受一个单词并搜索一堆句子以查看其中是否有任何一个包含该单词 之后我必须显示这些句子并突出显示该单词 我的计划是制作一个列表框并添加里面的句子 我的问题是如何突出显示该单词 我想是通过更改颜色 以便可以区分它
  • Rubocop 仅检查修改的行

    我想在终端上仅针对我在 git 版本化项目中修改的行运行 rubocop 目前 通过谷歌搜索 我看到了适用于整个修改文件的脚本 I found this https gist github com skanev 9d4bec97d5a682
  • Google 网络字体与实际字体文件 - 适用于所有设备

    我正在寻找使用 Josefin Sans 它已列在 Google 网络字体中 我还有 eot svg ttf 和 woff 这意味着与文件完全兼容 据我所知 我的主要问题是 哪个更好 Google 字体加载速度更快吗 是不是更加兼容呢 或者
  • 在 Go 函数中返回本地数组的切片安全吗?

    如果我返回作为函数或方法的局部变量的数组切片 会发生什么情况 Go 是否将数组数据复制到创建的切片中make 容量与切片大小或数组大小匹配吗 func foo uint64 var tmp 100 uint64 end 0 for tmp