上QQ阅读APP看书,第一时间看更新
2.3.4 CompositeEntry
在ch02\classpath目录下创建entry_composite.go文件,在其中定义CompositeEntry结构体,代码如下:
package classpath import "errors" import "strings" type CompositeEntry []Entry func newCompositeEntry(pathList string) CompositeEntry {...} func (self CompositeEntry) readClass(className string) ([]byte, Entry, error) {...} func (self CompositeEntry) String() string {...}
如前所述,CompositeEntry由更小的Entry组成,正好可以表示成[]Entry。在Go语言中,数组属于比较低层的数据结构,很少直接使用。大部分情况下,使用更便利的slice类型。构造函数把参数(路径列表)按分隔符分成小路径,然后把每个小路径都转换成具体的Entry实例,代码如下:
func newCompositeEntry(pathList string) CompositeEntry { compositeEntry := []Entry{} for _, path := range strings.Split(pathList, pathListSeparator) { entry := newEntry(path) compositeEntry = append(compositeEntry, entry) } return compositeEntry }
相信读者已经想到readClass()方法的代码了:依次调用每一个子路径的readClass()方法,如果成功读取到class数据,返回数据即可;如果收到错误信息,则继续;如果遍历完所有的子路径还没有找到class文件,则返回错误。readClass()方法的代码如下:
func (self CompositeEntry) readClass(className string) ([]byte, Entry, error) { for _, entry := range self { data, from, err := entry.readClass(className) if err == nil { return data, from, nil } } return nil, nil, errors.New("class not found: " + className) }
String()方法也不复杂。调用每一个子路径的String()方法,然后把得到的字符串用路径分隔符拼接起来即可,代码如下:
func (self CompositeEntry) String() string { strs := make([]string, len(self)) for i, entry := range self { strs[i] = entry.String() } return strings.Join(strs, pathListSeparator) }