調(diào)用 Go 函數(shù),該函數(shù)接受接口 A 的切片和結(jié)構(gòu) B 的切片(B 實(shí)現(xiàn) A)
有只小跳蛙
2021-06-30 13:08:43
我有以下類(lèi)型: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;調(diào)用接受類(lèi)型參數(shù)的函數(shù);即使Quote執(zhí)行Statement,[]Quote也沒(méi)有執(zhí)行[]Statement。[]Statement甚至不是一個(gè)接口。它有類(lèi)型slice of Statement. 雖然 Go 將類(lèi)型隱式轉(zhuǎn)換為接口類(lèi)型,但它不會(huì)從類(lèi)型A切片到接口切片的隱式轉(zhuǎn)換B。我們可以將引號(hào)顯式轉(zhuǎn)換為語(yǔ)句: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 quotesstatements := make([]Statement, len(conversation))for i, quote := range conversation { statements[i] = quote}Replay(statements)現(xiàn)在說(shuō) Replay 是一個(gè)庫(kù)的一部分,它希望能夠輕松使用 Replay。只要這些對(duì)象實(shí)現(xiàn) Statement 接口,它就允許您使用任何對(duì)象切片調(diào)用 Replay。為此,它具有以下轉(zhuǎn)換方法: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}回放看起來(lái)像這樣:func Replay(its interface{}) { conversation := ConvertToStatements(its) for _, statement := range conversation { fmt.Println(statement.Say()) }}我們現(xiàn)在可以直接用引號(hào)調(diào)用 Replay:Replay(conversation)最后,我的問(wèn)題是:有沒(méi)有更簡(jiǎn)單的方法可以讓 Replay 接受任何類(lèi)型 A 的切片,只要 A 實(shí)現(xiàn) Statement 接口?
查看完整描述