embedded式匿名接口的结构的含义?
sort
包:
type Interface interface { Len() int Less(i, j int) bool Swap(i, j int) } ... type reverse struct { Interface }
匿名Interface
在结构reverse
的含义是什么?
通过这种方式,reverse可以实现sort.Interface
,我们可以重写一个特定的方法,而不必定义所有的方法
type reverse struct { // This embedded Interface permits Reverse to use the methods of // another Interface implementation. Interface }
注意在这里它是如何交换(j,i)
而不是(i,j)
,这也是结构reverse
声明的唯一方法,即使reverse
实现sort.Interface
// 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) }
无论在这个方法中传递什么结构,我们都将其转换为一个新的reverse
结构。
// Reverse returns the reverse order for data. func Reverse(data Interface) Interface { return &reverse{data} }
如果你认为如果这种方法是不可能的,你会怎么做呢?
- 在
sort.Interface
添加另一个Reverse
方法? - 创build另一个ReverseInterface?
- …?
任何这种改变都需要在数千个想要使用标准反向function的软件包中有许多更多的代码。
好的,接受的答案帮助我理解,但我决定发表一个我认为更适合我的思维的解释。
“Effective Go”有embedded其他接口的接口的例子:
// ReadWriter is the interface that combines the Reader and Writer interfaces. type ReadWriter interface { Reader Writer }
和embedded其他结构的结构体:
// ReadWriter stores pointers to a Reader and a Writer. // It implements io.ReadWriter. type ReadWriter struct { *Reader // *bufio.Reader *Writer // *bufio.Writer }
但是没有提到embedded接口的结构。 我很困惑,看到这个sort
包:
type Interface interface { Len() int Less(i, j int) bool Swap(i, j int) } ... type reverse struct { Interface }
但是这个想法很简单。 这几乎是一样的:
type reverse struct { IntSlice // IntSlice struct attaches the methods of Interface to []int, sorting in increasing order }
IntSlice
被提升为reverse
。
和这个:
type reverse struct { Interface }
意味着sort.reverse
可以embedded任何实现接口sort.Interface
结构,以及接口所具有的任何方法,它们将被提升为reverse
。
sort.Interface
有方法Less(i, j int) bool
现在可以被覆盖:
// 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) }
我对理解的困惑
type reverse struct { Interface }
是我认为一个结构总是有固定的结构,即固定types的固定数量的字段。
但以下certificate我错了:
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"}) }
该声明
type reverse struct { Interface }
使您能够实现与接口Interface
所有functionreverse
初始化。 例:
&reverse{sort.Intslice([]int{1,2,3})}
这样,由embedded式Interface
值实现的所有方法都会被填充到外部,而您仍然可以reverse
重写其中的一些方法,例如Less
反向sorting。
这是使用sort.Reverse
时实际发生的情况。 你可以阅读关于在规范的结构部分embedded。
我也会给我解释。 sort
包定义了一个未导出的typesreverse
,它是一个embedded了Interface
的结构。
type reverse struct { // This embedded Interface permits Reverse to use the methods of // another Interface implementation. Interface }
这允许反向使用另一个接口实现的方法。 这就是所谓的composition
,这是Go的一个强大function。
Less
方法reverse
调用embedded式Interface
值的Less
方法,但将索引翻转后,反转sorting结果的顺序。
// 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) }
Len
和Swap
的另外两种reverse
方法,都是由原始的Interface
值隐式提供的,因为它是一个embedded的字段。 导出的Reverse
函数返回包含原始Interface
值的reverse
types的实例。
// Reverse returns the reverse order for data. func Reverse(data Interface) Interface { return &reverse{data} }