当前位置:   article > 正文

golang struct里面嵌入interface_struct 中含有interface{}

struct 中含有interface{}

最近在看context底层源码时发现了一个奇怪的用法:struct里边嵌入interface,struct又没有完全实现interface的所有接口,以前真心没注意到这种用法,只见过interface嵌套interface的,决定提笔记录一下。

直接上源码吧:src\context\context.go

  1. type Context interface {
  2. Deadline() (deadline time.Time, ok bool)
  3. Done() <-chan struct{}
  4. Err() error
  5. Value(key interface{}) interface{}
  6. }

cancelCtx 结构体的定义和具体实现 

  1. type cancelCtx struct {
  2. Context
  3. mu sync.Mutex // protects following fields
  4. done atomic.Value // of chan struct{}, created lazily, closed by first cancel call
  5. children map[canceler]struct{} // set to nil by the first cancel call
  6. err error // set to non-nil by the first cancel call
  7. }
  8. func (c *cancelCtx) Value(key interface{}) interface{} {
  9. if key == &cancelCtxKey {
  10. return c
  11. }
  12. return c.Context.Value(key)
  13. }
  14. func (c *cancelCtx) Done() <-chan struct{} {
  15. d := c.done.Load()
  16. if d != nil {
  17. return d.(chan struct{})
  18. }
  19. c.mu.Lock()
  20. defer c.mu.Unlock()
  21. d = c.done.Load()
  22. if d == nil {
  23. d = make(chan struct{})
  24. c.done.Store(d)
  25. }
  26. return d.(chan struct{})
  27. }
  28. func (c *cancelCtx) Err() error {
  29. c.mu.Lock()
  30. err := c.err
  31. c.mu.Unlock()
  32. return err
  33. }

 timerCtx 结构体的定义和具体实现 

  1. type timerCtx struct {
  2. cancelCtx
  3. timer *time.Timer // Under cancelCtx.mu.
  4. deadline time.Time
  5. }
  6. func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
  7. return c.deadline, true
  8. }

Context接口有4个方法,但是cancelCtx只实现了3个方法,Deadline()它并没有实现,而timerCtx只实现了Deadline(),其他3个并没有实现。

在我的认知当中没见过这种写法,实现一个接口就是实现这个接口的所有方法,比如源码中的emptyCtx

  1. type emptyCtx int
  2. func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
  3. return
  4. }
  5. func (*emptyCtx) Done() <-chan struct{} {
  6. return nil
  7. }
  8. func (*emptyCtx) Err() error {
  9. return nil
  10. }
  11. func (*emptyCtx) Value(key interface{}) interface{} {
  12. return nil
  13. }
  14. func (e *emptyCtx) String() string {
  15. switch e {
  16. case background:
  17. return "context.Background"
  18. case todo:
  19. return "context.TODO"
  20. }
  21. return "unknown empty Context"
  22. }
  23. var (
  24. background = new(emptyCtx)
  25. todo = new(emptyCtx)
  26. )

当时看到这种用法,直接懵逼了,还是自己基础不牢。。。。

嵌入interface作为struct的一个匿名成员,就可以假设这个struct就是此成员interface的一个实现,而不管struct是否已经实现interface所定义的函数。

  1. type Student interface {
  2. Run()
  3. Walk()
  4. }
  5. type Pupil struct {
  6. age int
  7. Student
  8. }
  9. func NewPupil(age int) *Pupil{
  10. return &Pupil{age: age}
  11. }
  12. //func (p *Pupil) Run() {
  13. //
  14. //}
  15. //
  16. //func (p *Pupil) Walk(){
  17. //
  18. //}
  19. func main(){
  20. p := NewPupil(100)
  21. var s Student = p
  22. fmt.Printf("%#v\n",s)
  23. }

struct Pupil没有实现interface中的任何函数,只是在声明的时候把Student作为一个匿名成员,main函数能正常运行并没有报错,说明p确实被认为是Student的具体实现。

既然没有实现函数,那如何调用接口尼?答案就是 没有实现肯定是不能调用,一旦调用就crash。只能调用已经实现的函数。上边注释掉的 Run()和Walk() 放开哪个,s就可以调用哪个。。。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/907932
推荐阅读
相关标签
  

闽ICP备14008679号