从嵌入的结构体中访问字段。

huangapple go评论116阅读模式
英文:

accessing struct fields from embedded struct

问题

我想在一个结构体上定义一个方法来验证 HTTP 请求,但是我在访问结构体字段方面遇到了一些问题。

以下是我的代码:

  1. package main
  2. import "log"
  3. type ReqAbstract struct{}
  4. func (r *ReqAbstract) Validate() error {
  5. log.Printf("%+v", r)
  6. return nil
  7. }
  8. func (r *ReqAbstract) Validate2(req interface{}) error {
  9. log.Printf("%+v", req)
  10. return nil
  11. }
  12. type NewPostReq struct {
  13. ReqAbstract
  14. Title string
  15. }
  16. func main() {
  17. request := &NewPostReq{Title: "Example Title"}
  18. request.Validate()
  19. request.Validate2(request)
  20. }

当我运行这段代码时,我得到了以下结果:

  1. 2015/07/21 13:59:50 &{}
  2. 2015/07/21 13:59:50 &{ReqAbstract:{} Title:Example Title}

有没有办法在 Validate() 方法中像 Validate2() 方法那样访问结构体字段?

英文:

I want to define a method on a struct for validating http request. but I have some problems about accessing struct fields.

there is my code.

  1. package main
  2. import "log"
  3. type ReqAbstract struct{}
  4. func (r *ReqAbstract) Validate() error {
  5. log.Printf("%+v", r)
  6. return nil
  7. }
  8. func (r *ReqAbstract) Validate2(req interface{}) error {
  9. log.Printf("%+v", req)
  10. return nil
  11. }
  12. type NewPostReq struct {
  13. ReqAbstract
  14. Title string
  15. }
  16. func main() {
  17. request := &NewPostReq{Title: "Example Title"}
  18. request.Validate()
  19. request.Validate2(request)
  20. }

When I run this code, I get the below result

  1. 2015/07/21 13:59:50 &{}
  2. 2015/07/21 13:59:50 &{ReqAbstract:{} Title:Example Title}

is there any way to access struct fields on Validate() method like Validate2() method?

答案1

得分: 8

你不能从内部结构访问外部结构的字段,只能从外部访问内部的字段。你可以使用组合来实现:

  1. type CommonThing struct {
  2. A int
  3. B string
  4. }
  5. func (ct CommonThing) Valid() bool {
  6. return ct.A != 0 && ct.B != ""
  7. }
  8. type TheThing struct {
  9. CommonThing
  10. C float64
  11. }
  12. func (tt TheThing) Valid() bool {
  13. return tt.CommonThing.Valid() && tt.C != 0
  14. }

在这个例子中,TheThing 结构体通过组合 CommonThing 结构体来使用它的字段和方法。TheThing 结构体也可以定义自己的字段和方法。

英文:

You cannot access outer struct fields from inner struct. Only inner fields from the outer. What you can do is composing:

  1. type CommonThing struct {
  2. A int
  3. B string
  4. }
  5. func (ct CommonThing) Valid() bool {
  6. return ct.A != 0 && ct.B != ""
  7. }
  8. type TheThing struct {
  9. CommonThing
  10. C float64
  11. }
  12. func (tt TheThing) Valid() bool {
  13. return tt.CommonThing.Valid() && tt.C != 0
  14. }

答案2

得分: 3

你可以定义一个指向自身的字段。

  1. package main
  2. import (
  3. "log"
  4. )
  5. type ReqAbstract struct {
  6. selfPointer interface{}
  7. }
  8. func (r *ReqAbstract) Assign(i interface{}) {
  9. r.selfPointer = i
  10. }
  11. func (r *ReqAbstract) Validate() error {
  12. log.Printf("%+v", r.selfPointer)
  13. return nil
  14. }
  15. func (r *ReqAbstract) Validate2(req interface{}) error {
  16. log.Printf("%+v", req)
  17. return nil
  18. }
  19. type PostReq struct {
  20. ReqAbstract
  21. Title string
  22. }
  23. func NewPostReq(title string) *PostReq {
  24. pr := &PostReq{Title: title}
  25. pr.Assign(pr)
  26. return pr
  27. }
  28. func main() {
  29. request := NewPostReq("Example Title")
  30. request.Validate()
  31. request.Validate2(request)
  32. }

这将输出:

2009/11/10 23:00:00 &{ReqAbstract:{selfPointer:0x10438180} Title:Example Title}
2009/11/10 23:00:00 &{ReqAbstract:{selfPointer:0x10438180} Title:Example Title}

请查看playground

英文:

You can define filed with point to himself

  1. package main
  2. import (
  3. "log"
  4. )
  5. type ReqAbstract struct{
  6. selfPointer interface{}
  7. }
  8. func (r *ReqAbstract) Assign(i interface{}) {
  9. r.selfPointer = i
  10. }
  11. func (r *ReqAbstract) Validate() error {
  12. log.Printf("%+v", r.selfPointer)
  13. return nil
  14. }
  15. func (r *ReqAbstract) Validate2(req interface{}) error {
  16. log.Printf("%+v", req)
  17. return nil
  18. }
  19. type PostReq struct {
  20. ReqAbstract
  21. Title string
  22. }
  23. func NewPostReq(title string) *PostReq {
  24. pr := &PostReq{Title:title}
  25. pr.Assign(pr)
  26. return pr
  27. }
  28. func main() {
  29. request := NewPostReq("Example Title")
  30. request.Validate()
  31. request.Validate2(request)
  32. }

This will output:

2009/11/10 23:00:00 &{ReqAbstract:{selfPointer:0x10438180} Title:Example Title}
2009/11/10 23:00:00 &{ReqAbstract:{selfPointer:0x10438180} Title:Example Title}

Check playground

huangapple
  • 本文由 发表于 2015年7月21日 19:16:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/31537549.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定