在Golang中返回接口

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

Returning interfaces in Golang

问题

我正在尝试在一个结构体上编写一个方法,该方法接受一个接口类型,并将该接口类型转换为相应的类型后返回。

type Model interface {
	GetEntity()
}

type TrueFalseQuestions struct {
	//一些内容
}

func (q *TrueFalseQuestions) GetEntity() {
	//一些内容
}

type MultiQuestions struct {
	//一些内容
}

func (q *MultiQuestions) GetEntity() {
	//一些内容
}

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{})
}

所以当我使用TrueFalseQuestions类型调用GetModel()时,我希望自动返回一个TrueFalseQuestions类型。我认为这意味着我的GetModel()方法应该返回一个Model类型。这样,如果我传递一个MultiQuestion类型,就会返回一个MultiQuestion结构体。

英文:

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.

答案1

得分: 4

当返回类型为Model时,你不能直接返回TrueFalseQuestions。它将始终被隐式地包装在Model接口中。

要获取TrueFalseQuestions,你需要使用类型断言(还需要注意指针和值之间的区别)。

// 这应该是一个指针,因为接口方法都有指针接收器
q := &TrueFalseQuestions{}
q = man.GetModel(&TrueFalseQuestions{}).(*TrueFalseQuestions)

当然,如果你得到了MultiQuestions,这可能会引发恐慌,所以你应该检查ok值,或者使用类型切换。

switch q := man.GetModel(&TrueFalseQuestions{}).(type) {
case *TrueFalseQuestions:
	// q 是 TrueFalseQuestions
case *MultiQuestions:
	// q 是 MultiQuestions
default:
	// 意外的类型
}
英文:

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
}

答案2

得分: 1

你可以使用类型断言来对返回的值进行断言。

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

英文:

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)
	}

}

<kbd>playground</kbd>

huangapple
  • 本文由 发表于 2014年8月2日 03:54:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/25087726.html
匿名

发表评论

匿名网友

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

确定