dphe5602
2014-08-01 19:54
浏览 95
已采纳

在Golang中返回接口

I am trying to write a method on a struct that takes in a interface type and returns that interface type but converted to the appropriate type.

type Model interface {
    GetEntity()
}

type TrueFalseQuestions struct {
   //some stuff
}

func (q *TrueFalseQuestions) GetEntity() {
   //some stuff
}

type MultiQuestions struct {
    //some stuff
}

func (q *MultiQuestions) GetEntity() {
    //some stuff
}


type Manager struct {
}


func (man *Manager) GetModel(mod Model) Model {
    mod.GetEntity()
    return mod
}

func main() {
    var man Manager

    q := TrueFalseQuestions {}
    q = man.GetModel(&TrueFalseQuestions {})
}

So when I call GetModel() with type TrueFalseQuestions I want to automatically return a TrueFalseQuestions type. I figured that would mean that my GetModel() method should return a Model type. That way if I pass a MultiQuestion type a MultiQuestion struct is returned.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • duanjianl183188 2014-08-01 20:04
    已采纳

    You can't directly return a TrueFalseQuestions when the return type is Model. It will always be implicitly wrapped in a Model interface.

    To get the TrueFalseQuestions back, you need to use a type-assertion. (you also need watch out for pointers vs values)

    // this should be a pointer, because the interface methods all have pointer receivers
    q := &TrueFalseQuestions{}
    q = man.GetModel(&TrueFalseQuestions{}).(*TrueFalseQuestions)
    

    That of course can panic if you got a MultiQuestions, so you should check the ok value, or use a type switch

    switch q := man.GetModel(&TrueFalseQuestions{}).(type) {
    case *TrueFalseQuestions:
        // q isTrueFalseQuestions
    case *MultiQuestions:
        // q is MultiQuestions
    default:
        // unexpected type
    }
    
    点赞 打赏 评论
  • douchun5976 2014-08-01 20:04

    You can't, however you can use type assertion on the returned value.

    func main() {
        var man Manager
    
        tfq := &TrueFalseQuestions{}
        q := man.GetModel(tfq)
        if v, ok := q.(*TrueFalseQuestions); ok {
            fmt.Println("v is true/false", v)
        } else if v, ok := q.(*MultiQuestions); ok {
            fmt.Println("v is mq", v)
        } else {
            fmt.Println("unknown", q)
        }
    
    }
    

    playground

    点赞 打赏 评论

相关推荐 更多相似问题