2017-10-20 14 views
3

私は別の型を返す2つの関数を持つサードパーティのライブラリを使って作業しています。例えば。 ArticleResponseおよびCommentResponse未知のパラメータ型の渡し関数リファレンスが

これらの関数のいずれかを呼び出した結果を自分の関数に渡したいと思います。その関数の第2引数として、その応答をstdoutに出力する方法を記述した関数参照を渡したいと思います。

response := GetArticles() 
processResponse(response, printResponse) 

func printResponse(response <what_type?>) { 
    for i := range response.Articles { 
     fmt.Println(response.Articles[i].Title) 
    } 
} 

それは強制またはprintResponse関数はそのパラメータに渡されることを期待するのかを知っているように、ジェネリック型を作成する方法を私に明確ではありません。

私がここで何をしようとしているかについての十分な説明を提供していない場合は、教えてください。私は質問を編集/更新します。この場合

+0

もしあなたがちょうど2つのタイプを扱っているのであれば、これ以上のこともできるでしょう。https://play.golang.org/p/cVtlTu61b5 – mkopriva

答えて

6

あなたの唯一の現実的な選択肢はprocessResponseinterface{}及びこれを受け入れる機能を受け入れるようにして、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()) 
    } 
} 

を作成することができます

0

はその後ArticleResponse & CommentResponseContentListインターフェースとAticle & CommentContentインタフェースを実装する必要が実装する必要があります。

関連する問題