あなたの唯一の現実的な選択肢はprocessResponse
interface{}
及びこれを受け入れる機能を受け入れるようにして、printResponse
に同じ空のインターフェイスを受け入れ、それをタイプアサート(またはタイプのスイッチを使用)するためのものです。たとえば:
func main() {
response := GetArticles()
processResponse(response, printResponse)
}
func processResponse(response interface{}, printResponse func(interface{}))
{
// Process
printResponse(response)
}
func printResponse(response interface{}) {
switch r = reponse.(type) {
case ArticleResponse:
for i := range r.Articles {
fmt.Println(r.Articles[i].Title)
}
case CommentResponse:
for i := range r.Comments {
fmt.Println(r.Comments[i].Topic, r.Comments[i].User)
}
}
}
しかし、より一般的なスタイルは、Printメソッド(または類似)を持っているあなたの応答自身のためになる、とあなたの処理機能のためにその一般的な方法を表すインタフェースを受け入れること。たとえば:processResponse
機能のみ、それは自分自身を印刷できるのですいくつかのタイプを得たことを知っていながら
type ArticleReponse struct {
// ...
}
func (a ArticleReponse) Print() {
for i := range a.Articles {
fmt.Println(a.Articles[i].Title)
}
}
type CommentResponse struct {
// ...
}
func (c CommentResponse) Print() {
for i := range c.Comments {
fmt.Println(c.Comments[i].Topic, c.Comment[i].User)
}
}
type Response interface {
Print()
}
func main() {
response := GetArticles()
processResponse(response)
}
func processResponse(response Response)
{
// Process
response.Print()
}
このスタイルは、レスポンスの種類自体が彼らの印刷動作を定義することができます。これにより、実際にどのタイプが与えられたかを知らなくても、これらのタイプと対話するために、processResponse
(または他のもの)が必要とする可能性があるResponseインターフェースに他のメソッドを追加することもできます。これにより、コードは実質的に壊れにくくなります。これは、各応答タイプの実際の実装の詳細に依存しなくなるためです。また、ユニットprocessReponse
を単体で、Response
インターフェイスを試してみることができます。あなたはContent
& ContentList
インターフェース
type Content interface {
GetTitle() string
}
type ContentList interface {
Contents() []Content
}
func printResponse(response ContentList) {
for content := range response.Contents() {
fmt.Println(content.GetTitle())
}
}
を作成することができます
もしあなたがちょうど2つのタイプを扱っているのであれば、これ以上のこともできるでしょう。https://play.golang.org/p/cVtlTu61b5 – mkopriva