Slice 的用途-作为栈的例子
遍历文件夹是一个我们经常遇到的操作,文件系统是一个树形结构,我经常喜欢拿这个作为练手例子,比方可以拿来考查递归,这个例子是一个遍历文件夹获取文件的函数,没有使用递归,只有20行左右的代码。
思路就是用两个slice来存储所需的数据,其中一个路径slice以栈的形式来存储需遍历的文件夹,出栈入栈循环遍历文件夹以及子文件夹:
func scanAll(path string) []string {
var result []string //结果集
paths := []string{path} //目录栈:存储需要遍历的文件夹,初始化时传入需要遍历的文件夹
for len(paths) > 0 { //目录栈不为空则不断循环
//出栈pop
dir := paths[len(paths)-1]
paths = paths[:len(paths)-1]
//遍历pop出的的文件夹
files, _ := ioutil.ReadDir(dir)
for _, f := range files {
p := dir + "/" + f.Name() //拼接路径
if f.IsDir() {
paths = append(paths, p) //如果是文件夹类型则入栈
} else {
result = append(result, p) //如果是文件则存结果
}
}
}
return result
}
改成递归的话可以这么写:
func scanAllByRecursive(path string) []string {
var result, tmp []string //结果集
files, _ := ioutil.ReadDir(path)
for _, f := range files {
p := path + "/" + f.Name()
if f.IsDir() {
tmp = scanAllByRecursive(p)
} else {
result = append(result, p)
}
}
return append(result, tmp...)
}
还可以这么写,把存储容器放在外部,作为接收器:
type Stack []string
var result Stack
result.scanAllByRecursive(".")
func (result *Stack) scanAllByRecursive(path string) {
files, _ := ioutil.ReadDir(path)
for _, f := range files {
p := path + "/" + f.Name()
if f.IsDir() {
result.scanAllByRecursive(p)
} else {
*result = append(*result, p)
}
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: