为了账号安全,请及时绑定邮箱和手机立即绑定

模板对象字段强制执行

模板对象字段强制执行

Go
qq_笑_17 2021-12-06 16:56:19
Go 提供了很好的 HTML 模板功能,但是对我来说,确保某些字段始终可用于我的应用程序中的模板是很重要的。一个很好的例子是标题字段,它需要显示在每个 HTML 页面上。鉴于以下页面:HomeRegisterContact我可能会为模板系统创建以下对象:HomePagestructRegisterPagestructContactPagestruct是否有推荐的方法来确保每个页面的结构都有可用的某些字段?理想情况下,我会通过多态来实现这一点,但这在 Go 中并未得到官方支持。另一种选择,嵌入不会出现任何强制执行,即所有子结构的可嵌入父结构,但不必须。如果我没有足够清楚地表达我的问题,请告诉我。
查看完整描述

1 回答

?
梦里花落0921

TA贡献1772条经验 获得超5个赞

执行模板不强制任何参数,Template.Execute()接受类型的值interface{}。


您是创建HomePage,RegisterPage和ContactPage结构的人。是什么阻止您嵌入BasePage具有所需字段的结构?你担心你会忘记它吗?你会在第一次测试时注意到它,我不会担心:


type BasePage struct {

    Title string

    Other string

    // other required fields...

}


type HomePage struct {

    BasePage

    // other home page fields...

}


type RegisterPage struct {

    BasePage

    // other register page fields...

}

如果您想从代码中检查页面结构是否嵌入了BasePage,我推荐另一种方法:接口。


type HasBasePage interface {

    GetBasePage() BasePage

}

HomePage实现它的示例:


type HomePage struct {

    BasePage

    // other home page fields...

}


func (h *HomePage) GetBasePage() BasePage {

    return h.BasePage

}

现在显然只有具有GetBasePage()方法的页面才能作为值传递HasBasePage:


var page HasBasePage = &HomePage{} // Valid, HomePage implements HasBasePage

如果你不想使用接口,你可以使用reflect包来检查一个值是否是一个结构值,以及它是否嵌入了另一个接口。嵌入的结构出现并且可以像普通字段一样访问,例如 with Value.FieldByName(),类型名称是字段名称。


reflect用于检查值是否嵌入的示例代码BasePage:


page := &HomePage{BasePage: BasePage{Title: "Home page"}}


v := reflect.ValueOf(page)

if v.Kind() == reflect.Ptr {

    v = v.Elem()

}

if v.Kind() != reflect.Struct {

    fmt.Println("Error: not struct!")

    return

}

bptype := reflect.TypeOf(BasePage{})

bp := v.FieldByName(bptype.Name()) // "BasePage"

if !bp.IsValid() || bp.Type() != bptype {

    fmt.Println("Error: struct does not embed BasePage!")

    return

}


fmt.Printf("%+v", bp)

输出(在 上尝试Go Playground):


{Title:Home page Other:}


查看完整回答
反对 回复 2021-12-06
  • 1 回答
  • 0 关注
  • 159 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信