0

0

如何在 Go 中正确共享嵌入结构体指针

霞舞

霞舞

发布时间:2026-01-05 15:08:23

|

341人浏览过

|

来源于php中文网

原创

如何在 Go 中正确共享嵌入结构体指针

go 中,当使用匿名字段(嵌入)的指针类型时,需通过父结构体实例显式引用该嵌入字段(如 `rcv.controller`),而非直接写类型名 `base.controller`,才能实现指针共享。

Go 的结构体匿名字段(embedded field)虽支持“提升”(promotion)——即嵌入类型的字段和方法可被外层结构体直接调用——但在结构体字面量初始化时,匿名字段仍需以字段名(即其类型名)作为键来赋值。关键在于:该字段名在语法上就是其类型名,但初始化时必须是表达式(expression),不能是类型(type)本身

回到你的代码:

type controller struct {
    *base.Controller  // 匿名字段:类型为 *base.Controller,字段名为 Controller
    store *data
}

type expiredError struct {
    *base.Controller  // 同样,字段名为 Controller
    local string
}

当你尝试这样写:

return &expiredError{base.Controller, rcv.Local} // ❌ 错误!base.Controller 是类型,不是值

编译器报错 type base.Controller is not an expression,正是因为 base.Controller 是一个类型名,而结构体字面量中 {...} 要求每个位置都是可求值的表达式(比如变量、字段访问、函数调用等)。

✅ 正确做法是:*通过接收者 rcv 访问已嵌入的 `base.Controller字段**。由于 Go 规定匿名字段的字段名默认为其类型名(去掉包名后),因此rcv.base.Controller的字段名就是Controller(注意:不是base.Controller,而是Controller` —— 类型名作为字段标识符)。

GPTBots
GPTBots

企业级AI智能体构建平台

下载

所以应改为:

return &expiredError{
    Controller: rcv.Controller, // ✅ 正确:rcv.Controller 是 *base.Controller 类型的值(即指针)
    local:      rcv.Local,
}
? 提示:虽然 Controller 是匿名字段,但它在结构体内有明确的字段名(即 Controller),可通过 rcv.Controller 直接访问;这与 rcv.Title 能访问 base.Controller.Title 是同一机制的体现。

完整修正后的 validate 方法如下:

func (rcv *controller) validate() error {
    // ... 其他逻辑

    if time.Now().Unix() > rcv.store.Expired {
        maccount.Delete(rcv.store.Email, rcv.Local)
        return &expiredError{
            Controller: rcv.Controller, // 共享同一份 *base.Controller 实例
            local:      rcv.Local,
        }
    }

    return nil
}

? 注意事项

  • 嵌入的是指针(*base.Controller)而非值类型,因此 rcv.Controller 本身就是一个指针,直接赋值即可实现零拷贝共享
  • 若 expiredError 后续调用 c.Title = "xxx" 或 c.Render() 等方法,将作用于与 controller 完全相同的 base.Controller 实例,确保状态一致;
  • 不要误写为 &rcv.Controller(会取地址再取地址,导致类型不匹配)或 rcv.base.Controller(Go 不支持包限定的字段访问)。

✅ 总结:嵌入指针的共享本质是复用字段值,而该字段在结构体内有隐式名称(即类型名),只需通过 rcv.字段名 引用即可,无需新建或转换。这是 Go 组合优于继承的核心实践之一。

相关专题

更多
mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

179

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

276

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

252

2025.06.11

c++标识符介绍
c++标识符介绍

本专题整合了c++标识符相关内容,阅读专题下面的文章了解更多详细内容。

121

2025.08.07

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

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

194

2025.06.09

golang结构体方法
golang结构体方法

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

186

2025.07.04

漫蛙2入口地址合集
漫蛙2入口地址合集

本专题整合了漫蛙2入口汇总,阅读专题下面的文章了解更多详细内容。

4

2026.01.06

AO3中文版地址汇总
AO3中文版地址汇总

本专题整合了AO3中文版地址合集,阅读专题下面的文章了解更多详细内容。

3

2026.01.06

python cv2模块教程大全
python cv2模块教程大全

本专题整合了python cv2模块相关教程,阅读专题下面的文章了解更多详细教程。

7

2026.01.06

热门下载

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

精品课程

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

共32课时 | 3.4万人学习

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

共10课时 | 0.8万人学习

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

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