0

0

如何在 Go 中获取函数返回值的指针

聖光之護

聖光之護

发布时间:2026-02-25 10:39:27

|

520人浏览过

|

来源于php中文网

原创

如何在 Go 中获取函数返回值的指针

go 语言禁止对函数调用表达式(如 time.now())直接取地址,因其返回值不属于“可寻址”(addressable)对象;唯一合规方式是先赋值给变量,再取其地址。

go 语言禁止对函数调用表达式(如 time.now())直接取地址,因其返回值不属于“可寻址”(addressable)对象;唯一合规方式是先赋值给变量,再取其地址。

在 Go 中,& 操作符仅能作用于可寻址的表达式(addressable expressions)。根据 Go 语言规范,可寻址的对象必须满足以下之一:

  • 变量(例如 t := time.Now(); &t)
  • 指针解引用(例如 &(*p))
  • 切片索引操作(例如 &s[0])
  • 可寻址结构体的字段(例如 &s.Field)
  • 可寻址数组的索引(例如 &a[5])

⚠️ 函数调用(如 time.Now())和方法调用(如 x.String())明确不在该列表中——因此 &time.Now() 是语法错误,编译器会报错:cannot take the address of time.Now()。

为什么不允许?——底层与设计考量

从实现角度看,函数返回值可能位于 CPU 寄存器或栈帧中:

  • 若值暂存在寄存器(常见于小返回值优化),它根本没有内存地址;
  • 若暂存在栈上,其生命周期仅限于当前函数调用栈帧;若允许取地址并逃逸(escape),将导致悬垂指针(dangling pointer),破坏内存安全。

Go 的设计哲学强调显式优于隐式:如果需要一个可寻址的值,开发者必须显式声明变量来承载它,而非依赖编译器“悄悄分配内存”。这既保证了行为可预测,也避免了因隐式堆分配带来的性能模糊性。

超级简历WonderCV
超级简历WonderCV

免费求职简历模版下载制作,应届生职场人必备简历制作神器

下载

正确写法:先赋值,再取址

package main

import (
    "fmt"
    "time"
)

func main() {
    // ✅ 正确:先绑定到变量,再取地址
    now := time.Now()
    ptr := &now

    fmt.Printf("Time: %v, Address: %p\n", *ptr, ptr)
}

进阶技巧:封装为辅助函数(保持简洁性)

若频繁需要 *time.Time,可封装成一行式辅助函数(注意:本质仍是先赋值):

func nowPtr() *time.Time {
    t := time.Now()
    return &t // t 在函数内有效,返回其地址 → 编译器自动将其分配到堆(escape analysis)
}

// 使用
t := nowPtr() // t 类型为 *time.Time

? 提示:return &t 触发逃逸分析(escape analysis),编译器会将 t 分配到堆上,确保返回的指针长期有效。可通过 go build -gcflags="-m" 验证。

常见误区澄清

  • ❌ &struct{X int}{1} 是合法的 —— 因为复合字面量(composite literal)属于规范中明确允许取址的特例;
  • ❌ &f()(无论 f 返回单值还是多值)始终非法;
  • ❌ 试图用 unsafe 绕过限制不仅不可移植,且违反内存安全模型,绝对不推荐

总结

场景 是否允许 &expr 原因
&time.Now() ❌ 编译失败 函数调用非 addressable
t := time.Now(); &t ✅ 合法 变量是 addressable
&struct{A int}{42} ✅ 合法 复合字面量是 addressable 特例

简言之:Go 要求“可寻址性”必须由程序员显式建立,而非由语言隐式提供。 接受这一约束,不仅能写出更清晰、更安全的代码,也更贴近 Go 的工程化设计本意。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

智谱清言 - 免费全能的AI助手
智谱清言 - 免费全能的AI助手

智谱清言 - 免费全能的AI助手

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

207

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

242

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

350

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

212

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

405

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

365

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

200

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1091

2025.06.17

Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法
Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法

本专题系统整理Steam官网最新可用入口,涵盖网页版登录地址、新用户注册流程、账号登录方法及官方游戏商店访问说明,帮助新手玩家快速进入Steam平台,完成注册登录并管理个人游戏库。

0

2026.02.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 5.5万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号