나는 다음과 같은 유형이 : 내가 왜 함수의 매우 잘 이해하고 있다고 생각전화 이동 기능 (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 Replay(its interface{}) {
conversation := ConvertToStatements(its)
for _, statement := range conversation {
fmt.Println(statement.Say())
}
}
우리는 지금 직접 따옴표와 함께 재생을 호출 할 수 있습니다 :
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
}
재생은 다음과 같습니다
Replay(conversation)
마지막으로, 내 질문 : A가 Statement 인터페이스를 구현하는 한 Replay가 A 유형의 슬라이스를 허용 할 수있는 더 간단한 방법이 있습니까?