必须匿名嵌入beego.controller并重写init方法且首行调用c.controller.init;否则ctx、data等字段为nil导致panic。 usercontroller结构体需直接嵌入beego.controller,init中必须先调用父类init再添加自定义逻辑如tplprefix设置。

要在Beego框架中让自定义控制器继承标准行为并重写初始化逻辑,必须严格遵循嵌入beego.Controller结构体的约定,同时正确覆盖Init方法以注入自定义上下文初始化动作——直接定义Init而不调用父级初始化会导致Ctx、Data等核心字段为nil,引发panic。
控制器结构体必须匿名嵌入beego.Controller
新建controllers/user.go文件,定义UserController结构体时,【必须使用匿名嵌入而非组合或指针】:
type UserController struct {
beego.Controller
}
这一步不可省略或替换为*beego.Controller或单独声明字段。Beego的反射注册机制只识别这种嵌入形式,否则路由无法绑定该控制器。
重写Init方法并手动调用父类Init
在UserController中添加Init方法,注意参数签名必须与beego.Controller.Init完全一致:
func (c *UserController) Init(ct *context.Context, childName string, app interface{}) {
c.Controller.Init(ct, childName, app)
}
这行调用是关键:它完成Ctx、Data、controllerName等基础字段的初始化。漏掉这句,后续所有this.Ctx.WriteString或this.Data赋值都会触发nil pointer dereference panic。
在此之后可追加自定义逻辑,例如预设通用模板路径:
c.TplPrefix = "user/"
c.Layout = "layouts/base.html"
验证Init是否生效的两个位置
方法一:在Prepare方法中打印日志
func (c *UserController) Prepare() {
beego.Info("Init已完成,Ctx可用:", c.Ctx != nil)
}
方法二:在Get方法中直接使用Data容器
func (c *UserController) Get() {
c.Data["Title"] = "用户首页"
c.TplName = "index.tpl"
}
如果未正确调用c.Controller.Init,c.Data["Title"]赋值会失败,渲染时Data为空map。











