aşağıdaki türleri vardır: Ben neden bir işlevin oldukça iyi bir kavrayışa sahip düşünüyorumÇağrı Git fonksiyonu (B uygulayan 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())
}
}
o []Statement
tipinde bir parametre kabul eder, []Quote
ile çağrılmaz; Quote
, Statement
uygulandığında bile, []Quote
, []Statement
uygulanmaz. []Statement
, bir arayüz bile değil. Bu, slice of Statement
türüne sahiptir. Go, bir türden bir arabirim türüne dolaylı olarak dönüştürürken, A
türünde bir dilimden, B
arabiriminin bir dilimine örtük bir dönüşüm gerçekleştirmez.
Biz açıkça açıklamalara tırnak dönüştürebilirsiniz:
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)
Şimdi bu Tekrar o Replay kullanımı var ne kadar kolay kendi yolumdan gitmek istiyor kitaplığın bir parçası olduğunu söylüyorlar. Bu nesneler, Deyim arabirimini uyguladığı sürece, herhangi bir nesne dilimiyle Yeniden Oynat'ı çağırmanıza izin verir. Bunu yapmak için sahip olduğu Aşağıdaki dönüşüm yöntemi:
func Replay(its interface{}) {
conversation := ConvertToStatements(its)
for _, statement := range conversation {
fmt.Println(statement.Say())
}
}
Biz artık doğrudan tırnak Replay çağırabilirsiniz:
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
}
Tekrar şöyle
Replay(conversation)
Son olarak, sorum: A, Deyim arayüzünü uyguladığı sürece, Replay'in herhangi bir A türünde bir dilimi kabul etmesine izin vermenin daha basit bir yolu var mı?