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 协议》,转载必须注明作者和本文链接
每天进步一点点
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!