Golang 递归访问目录与函数修改数组的问题

我想写一个这样的函数:
访问一个目录下的所有*.db文件。并放入filepath[]中。filepath是一个结构体:

type filepath struct {
    fullpath string   //文件路径名
    filename string //文件名
}

写完了的程序是这个样子的,打印时:

package main

import (
    "io/ioutil"
    "strings"
    "path"
)

const rootpath string = "D://testfile/2345"

type filepath struct {
    fullpath string
    filename string
}

func main() {
    var files []filepath
    files = make([]filepath, 0, 1)
    //dir,_:=ioutil.ReadDir(rootpath)
    //递了个归
    readdir(rootpath, files)
    for _, v := range files {
        println(v.filename, v.fullpath)
    }
}

func readdir(dirs string, files []filepath) {

    dir, _ := ioutil.ReadDir(dirs)
    for _, v := range dir {
        if v.IsDir() {
            dir2 := path.Join(dirs, v.Name())
            readdir(dir2, files)
        } else {
            if strings.HasSuffix(v.Name(), ".db") {
                var str string = v.Name()
                files = append(files, filepath{fullpath: path.Join(dirs, str), filename: str})
            }
        }
    }
}
//输出:

(什么~~都没有 一脸懵b.jpg)```
像我这种JB型boy(脚本型语言boy)不常用指针就会有这种错误。加点信息调试下?

//把最后一个else 里加两句,变成下面的:
else {
if strings.HasSuffix(v.Name(), ".db") {
str := v.Name()
println("老地址", files)
files = append(files, filepath{fullpath: path.Join(dirs, str), filename: str})
println("新地址", files)
//println(len(files) )
}
//输出如下(一对一对看还是很方便 []里的数字含义为 [len/cap]):
老地址 [0/1]0xc042033f58
新地址 [1/1]0xc042033f58
老地址 [1/1]0xc042033f58
新地址 [2/2]0xc042054b00
老地址 [2/2]0xc042054b00
新地址 [3/4]0xc042066b00
老地址 [3/4]0xc042066b00
新地址 [4/4]0xc042066b00
老地址 [4/4]0xc042066b00
新地址 [5/8]0xc042036300
老地址 [5/8]0xc042036300
新地址 [6/8]0xc042036300
老地址 [6/8]0xc042036300
新地址 [7/8]0xc042036300
老地址 [7/8]0xc042036300
新地址 [8/8]0xc042036300


分析下,按照append的尿性,每次内存不够就添加 len的空间,会不会生成一段时的内存,重新分配给指针???
**先确认下会不会分配吧!!!!**
一共是八个append
1. 只有一个空间,正好 
1. 空间不够了,加 len   现在2个了
1. 空间又不够了 ,加len 现在4个了
1. 够 
1. 不够 加len 8个
1. 够
1. 够 
1. 够

内存指针变了3次,那么,就可以肯定,一开始的files = make([]filepath, 0, 1) 应该有第一组数据啊~
再打印下内存,println换下位置

func main() {
var files []filepath
files = make([]filepath, 0, 1)
//dir,_:=ioutil.ReadDir(rootpath)
//递了个归
println("老地址", files)
readdir(rootpath, files)
for _, v := range files {
println(v.filename, v.fullpath)
}
}

func readdir(dirs string, files []filepath) {
println("新地址", files)
dir, _ := ioutil.ReadDir(dirs)
for _, v := range dir {
if v.IsDir() {
dir2 := path.Join(dirs, v.Name())
readdir(dir2, files)
} else {
if strings.HasSuffix(v.Name(), ".db") {
str := v.Name()
files = append(files, filepath{fullpath: path.Join(dirs, str), filename: str})
//println(len(files) )
}
}
}
}
//打印信息如下:
老地址 [0/1]0xc042033f58
新地址 [0/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58
新地址 [1/1]0xc042033f58

我发现,头指针依旧是那个头指针,所以结论:
** 随着append增加,头指针依旧是那个头指针**
那么问题来了,为什么就是打印不出来!!!
难道,append有坑,加的东西没有给上?
写个小程序试试吧。

package main

func main() {
var p1 []int=[]int{1,2,3,4,5}
change(p1)
println(p1[5])
}
func change(p1 []int) {
p1=append(p1,2222)
}
//输出
panic :数组越界

此时,我真的是。。。。
我突然想到了什么东西!!!!
** 突然明白过来,p1是个切片, main中的p1始终指向 {1,2,3,4,5} 而不会指向{1,2,3,4,5,2222 }**
程序修改如下:

package main

func main() {
var p1 []int=[]int{1,2,3,4,5}
change2(&p1)
println(p1[5])
}
func change2(p1 *[]int) {
p1=append(p1,2222)
}
//输出: 2222

到这里,我又有了一想到了前面近乎完美的调试信息,就是这一段:
> 分析下,按照append的尿性,每次内存不够就添加 len的空间,会不会生成一段时的内存,重新分配给指针???
**先确认下会不会分配吧!!!!**
一共是八个append
1. 只有一个空间,正好 
1. 空间不够了,加 len   现在2个了
1. 空间又不够了 ,加len 现在4个了
1. 够 
1. 不够 加len 8个
1. 够
1. 够 
1. 够

我猜,99.9%的可能是   `一个文件夹中有8个.db文件`  我去看了一下,还真是。
我想到了两种解决方案:
1. 像上面的函数那样改指针(去TMD)
2. 返回一个新的切片

最后我选2,别人看起来也方便点,于是,整个程序就变成:

package main

import (
"io/ioutil"
"strings"
"path"
)

const rootpath string = "D://testfile/2345"

type filepath struct {
fullpath string
filename string
}

func main() {
var files []filepath
files = make([]filepath, 0, 1)
files= readdir(rootpath, files)
for _, v := range files {
println(v.filename, v.fullpath)
}
}

func readdir(dirs string, files []filepath) []filepath {
dir, _ := ioutil.ReadDir(dirs)
for _, v := range dir {
if v.IsDir() {
dir2 := path.Join(dirs, v.Name())
files=readdir(dir2, files)
} else {
if strings.HasSuffix(v.Name(), ".db") {
str := v.Name()
files = append(files, filepath{fullpath: path.Join(dirs, str), filename: str})
//println(len(files) )
}
}
}
return files
}

再说一下go 的 path吧,感觉功能有点少,并没有 go.getpath这个功能,只能自己手动记录文件路径。
唉,程序算是写完了吧,如果我上面写得有什么问题,希望大家指正。






你可能感兴趣的:(Golang 递归访问目录与函数修改数组的问题)