私は次の種類があります。コール構造体BのスライスとのインタフェースAのスライスを受け入れるゴー機能(BがAを実装)
type Statement interface {
Say() string
}
type Quote struct {
quote string
}
func (p Quote) Say() string {
return p.quote
}
func Replay(conversation []Statement) {
for _, statement := range conversation {
fmt.Println(statement.Say())
}
}
私がなぜ機能のかなり良い理解を持っていると思います[]Statement
のパラメータを受け取り、[]Quote
で呼び出すことはできません。 Quote
がStatement
を実装しても、[]Quote
には[]Statement
が実装されていません。 []Statement
はインタフェースでもありません。タイプはslice of Statement
です。 Goは型からインターフェイス型に暗黙的に変換されますが、タイプA
のスライスからインタフェースB
のスライスへの暗黙的な変換は行われません。
我々が明示的に文に引用符を変換することができます:
conversation := []Quote{
Quote{"Nice Guy Eddie: C'mon, throw in a buck!"},
Quote{"Mr. Pink: Uh-uh, I don't tip."},
Quote{"Nice Guy Eddie: You don't tip?"},
Quote{"Mr. Pink: Nah, I don't believe in it."},
Quote{"Nice Guy Eddie: You don't believe in tipping?"},
}
// This doesn't work
// Replay(conversation)
// Create statements from quotes
statements := make([]Statement, len(conversation))
for i, quote := range conversation {
statements[i] = quote
}
Replay(statements)
は今リプレイが、それはリプレイを使用するのですどのように簡単にその方法の外に行きたいライブラリの一部であると言います。これらのオブジェクトがStatementインタフェースを実装している限り、オブジェクトの任意のスライスでReplayを呼び出すことができます。そうするためには、以下の変換方法があります。
func ConvertToStatements(its interface{}) ([]Statement, error) {
itsValue := reflect.ValueOf(its)
itsKind := itsValue.Kind()
if itsKind != reflect.Array && itsKind != reflect.Slice {
return nil, fmt.Errorf("Expected items to be an Array or a Slice, got %s", itsKind)
}
itsLength := itsValue.Len()
items := make([]Statement, itsLength)
for i := 0; i < itsLength; i++ {
itsItem := itsValue.Index(i)
if item, ok := itsItem.Interface().(Statement); ok {
items[i] = item
} else {
return nil, fmt.Errorf("item #%d does not implement the Statement interface: %s", i, itsItem)
}
}
return items, nil
}
リプレイは、次のようになります。
func Replay(its interface{}) {
conversation := ConvertToStatements(its)
for _, statement := range conversation {
fmt.Println(statement.Say())
}
}
現在、直接引用符でリプレイを呼び出すことができます。
最後にReplay(conversation)
、私の質問を: AがStatementインターフェイスを実装している限り、Replayに任意のタイプAのスライスを受け入れるための簡単な方法はありますか?