2016-06-24 8 views
1

私は2匹のペット、Lucyという猫とFidoという犬を持っているとします。私は彼らに同じテクニック、「話す」の両方を教えました。私は見越して、私はインターフェイスにコード化されてきたので、より多くのペットを取得し、それらを別のトリックを教えしたいと思います将来的には 自分自身を繰り返すことなく、Goのインターフェースへのコーディング

package main                 

import "fmt"                 

type Pet interface {               
     speak() string              
}                    

type Dog struct {                
     speech string               
}                    

type Cat struct {                
     speech string               
}                    

func (c Cat) speak() string {             
     return c.speech              
}                    

func (d Dog) speak() string {             
     return d.speech              
}                    

func getSpeech(p Pet) string {            
     return p.speak()              
}                    

func main() {                 
     Fido := Dog{"woof"}             
     Lucy := Cat{"meow"}             

     fmt.Println("Fido says:", getSpeech(Fido)) // Fido says: woof 
     fmt.Println("Lucy says:", getSpeech(Lucy)) // Lucy says: meow 
} 

さて、これはうまく動作しますが、それは不必要と思われます詳細。私は明らかに自分自身を繰り返している。また、すべてのDogsが "woof"と言って、すべてのCatsが "meow"と言っていると仮定すると、構造体内の文字列を初期化するのは慣用的ですか?

インターフェイスの利点を失うことなく、このコードをよりドライなものに再構成するにはどうすればよいでしょうか?

+2

あなたは、構造体の埋め込みを使用して、一般的なフィールド/メソッドを委任することができますが、実際には、あなたはこの不自然な何かを見つけるつもりはありません。 – JimB

答えて

5

ます場合によっては共通のフィールドとメソッドを委譲するために基本型を埋め込むことができます。これは継承ではなく、合成による自動委任の一形態に過ぎません。これを使用して、JavaスタイルのOOP言語のように型階層を作成しないでください。

ここでspeakメソッドをSpeakerタイプに委譲できます。実際には、Speakerとそのメソッドは埋め込まれている構造体とは関係がないため、スピーカーはどの型を話しているのか、個々のインスタンスを知りません。

https://play.golang.org/p/Bof92jZsNh

type Speaker struct { 
    Saying string 
} 

func (s Speaker) speak() string { 
    return s.Saying 
} 

type Pet interface { 
    speak() string 
} 

type Dog struct { 
    Speaker 
} 

type Cat struct { 
    Speaker 
} 

func getSpeech(p Pet) string { 
    return p.speak() 
} 

func main() { 
    Fido := Dog{Speaker{Saying: "woof"}} 
    Lucy := Cat{Speaker{Saying: "meow"}} 

    fmt.Println("Fido says:", getSpeech(Fido)) // Fido says: woof 
    fmt.Println("Lucy says:", getSpeech(Lucy)) // Lucy says: meow 
} 
6

最初に:あなたのコードでは繰り返しは見えません。猫と犬がいて、それぞれの猫が何かを言うかもしれないし、それぞれの犬が何かをするかもしれません。このケースではありませんし、あなたの仮定が真である場合に

場合は、すべてのすべての犬横糸と、すべての猫の鳴き声方法について:

const dogTalk = "woof" 
func (d Dog) speak() string { return dogTalk; } 
// or even 
func (d Cat) speak() string { return "meow"; } 

(そして:ゴーでJavaをコーディングしないでください)

+0

CatとDog speak()メソッドを組み合わせて、それらがどのように同じであるかを確認する方法はありますか?そして:+1はJavaのアクセントを認識するためのものです。 – ridthyself

+1

はい、実際にはありますが、埋め込みが必要なので、完全に一致する必要があります。方法は次のとおりです:https://play.golang.org/p/M78lvvQvl_ – Kaedys

関連する問題