首先我们来看看 Java 中的Iterator接口,源码如下,它提供了remove和forEachRemaining两个默认方法实现。如果在 Go 语言中,该如何实现这样的结构呢?
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
话不多说,直接撸代码......
首先定义一个Iterator接口,代码如下:
type Iterator interface {
HasNext() bool
Next() any
Remove()
ForEachRemaining(action func(value any))
}
然后我们需要定义一个结构体,该结构体是Iterator接口的实现类型,代码如下:
注意观察AbstractIterator类型的代码结构。
type AbstractIterator struct {
Iterator // 嵌入接口
}
func (this AbstractIterator) Remove() {
panic("unsupported remove operation")
}
func (this AbstractIterator) ForEachRemaining(action function.Predicate) {
for this.Iterator.HasNext() {
if !action(this.Iterator.Next()) {
return
}
}
}
在AbstractIterator类型中我们实现了Iterator 接口 Remove 和 ForEachRemaining 方法提供默认实现逻辑。
这样一来,当我们要实现Iterator接口时,可以直接将AbstractIterator类型嵌入自定义的结构体中,如下所示:
type Itr struct {
AbstractIterator
......
}
那么,如何引用默认实现方法呢?
现在我们要用Itr类型实例引用ForEachRemaining方法,那么我们只需要将Itr实例作为参数,为其嵌入字段AbstractIterator初始化即可。
// 实例化 Itr 对象
itr := &Itr{}
// 初始化 AbstractIterator 属性, 避免间接调用 ForEachRemaining 方法时引发空指针错误
itr.AbstractIterator = AbstractIterator{Iterator: itr}
// 相当于 itr.AbstractIterator.ForEachRemaining
itr.ForEachRemaining(func(value any){
fmt.Println(value)
})