Meaning of a struct with embedded anonymous interface?
1 2 3 4 5 6 7 8 9 10 11 | type Interface interface { Len() int Less(i, j int) bool Swap(i, j int) } ... type reverse struct { Interface } |
struct
这样,反向实现了
无需定义其他所有对象
1 2 3 4 5 | type reverse struct { // This embedded Interface permits Reverse to use the methods of // another Interface implementation. Interface } |
请注意,这里是如何交换
1 2 3 4 | // Less returns the opposite of the embedded implementation's Less method. func (r reverse) Less(i, j int) bool { return r.Interface.Less(j, i) } |
无论此方法内部传递了什么结构,我们都会将其转换为新的
1 2 3 4 | // Reverse returns the reverse order for data. func Reverse(data Interface) Interface { return &reverse{data} } |
真正的价值在于,如果您认为如果无法采用这种方法,该怎么办。
任何此类更改都将需要跨数千个要使用标准反向功能的软件包的许多行代码。
好的,可以接受的答案帮助我理解了,但是我决定发表一个我认为更适合我的思维方式的解释。
" Effective Go"具有嵌入了其他接口的接口示例:
1 2 3 4 5 | // ReadWriter is the interface that combines the Reader and Writer interfaces. type ReadWriter interface { Reader Writer } |
以及一个嵌入了其他结构的结构:
1 2 3 4 5 6 | // ReadWriter stores pointers to a Reader and a Writer. // It implements io.ReadWriter. type ReadWriter struct { *Reader // *bufio.Reader *Writer // *bufio.Writer } |
但是没有提及嵌入接口的结构。我在
1 2 3 4 5 6 7 8 9 10 11 | type Interface interface { Len() int Less(i, j int) bool Swap(i, j int) } ... type reverse struct { Interface } |
但是这个想法很简单。几乎与以下内容相同:
1 2 3 | type reverse struct { IntSlice // IntSlice struct attaches the methods of Interface to []int, sorting in increasing order } |
和这个:
1 2 3 | type reverse struct { Interface } |
表示
1 2 3 4 | // Less returns the opposite of the embedded implementation's Less method. func (r reverse) Less(i, j int) bool { return r.Interface.Less(j, i) } |
我对理解的困惑
1 2 3 | type reverse struct { Interface } |
是因为我认为结构始终具有固定的结构,即固定类型的字段的数量固定。
但是以下事实证明我错了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package main import"fmt" // some interface type Stringer interface { String() string } // a struct that implements Stringer interface type Struct1 struct { field1 string } func (s Struct1) String() string { return s.field1 } // another struct that implements Stringer interface, but has a different set of fields type Struct2 struct { field1 []string dummy bool } func (s Struct2) String() string { return fmt.Sprintf("%v, %v", s.field1, s.dummy) } // container that can embedd any struct which implements Stringer interface type StringerContainer struct { Stringer } func main() { // the following prints: This is Struct1 fmt.Println(StringerContainer{Struct1{"This is Struct1"}}) // the following prints: [This is Struct1], true fmt.Println(StringerContainer{Struct2{[]string{"This","is","Struct1"}, true}}) // the following does not compile: // cannot use"This is a type that does not implement Stringer" (type string) // as type Stringer in field value: // string does not implement Stringer (missing String method) fmt.Println(StringerContainer{"This is a type that does not implement Stringer"}) } |
该声明
1 2 3 | type reverse struct { Interface } |
使您可以使用实现接口
1 | &reverse{sort.Intslice([]int{1,2,3})} |
这样,由嵌入式
这是使用
我也会给出解释。
1 2 3 4 5 | type reverse struct { // This embedded Interface permits Reverse to use the methods of // another Interface implementation. Interface } |
这允许反向使用其他接口实现的方法。这就是所谓的
1 2 3 4 | // Less returns the opposite of the embedded implementation's Less method. func (r reverse) Less(i, j int) bool { return r.Interface.Less(j, i) } |
1 2 3 4 | // Reverse returns the reverse order for data. func Reverse(data Interface) Interface { return &reverse{data} } |