将变量引用传递给WalkDirFunc函数。

huangapple go评论78阅读模式
英文:

Passing variable reference to WalkDirFunc

问题

我正在努力递归迭代给定目录,并将找到的文件名和大小存储在map[string]uint32中。我找到了一篇描述如何递归遍历指定目录的帖子,使用了path/filepath/WalkDir函数和WalkDirFunc。我对Go相对陌生,还没有找到一种将我的map引用传递给WalkDirFunc的方法,因为它的签名只指定了三个参数:

func main() {
	args := os.Args
	if len(args) != 2 {
		msg := fmt.Sprintf("Usage: %v <path_to_directory>", args[0])
		log.Fatal(msg)
	}

	fullPath := args[1]
	dirMap := make(map[string]uint32)

	filepath.WalkDir(fullPath, walk)

}

// 如何创建接受 &map[string]uint32 的参数
func walk(path string, entry fs.DirEntry, err error) error {
	if err != nil {
		return err
	}

	if !entry.IsDir() {
		// 将 entry 和它的大小添加到 dirMap

		file, err := os.Stat(path)
		if err != nil {
			log.Println("Error determining file size:", err)
		}

		size := file.Size()

		// 将路径和大小添加到 dirMap

	} else if entry.IsDir() {
		// 在这里进行递归

	} else {
		log.Println("Unhandled branch:")
		log.Println(entry.Info())
	}

	return nil
}

编辑:由于walk是传递给filepath.WalkDirWalkDirFunc,所以从这里开始传递map是必要的。在Python中,我会使用命名参数来实现这一点,但在Go中,最好的方法是什么?

func main() {
	args := os.Args
    ...

	fullPath := args[1]
	dirMap := make(map[string]uint32)

	// 在这里应该传递dirMap
	filepath.WalkDir(fullPath, walk)

}
英文:

I am working to recursively iterate through a given directory and store the name of files found and their sizes in a map[string]uint32. I've found a post describing how to recursively walk a specified directory using the path/filepath/WalkDir function and a WalkDirFunc.

I am relatively new to Go, and haven't been able to find a way to pass a reference to my map to the WalkDirFunc since its signature specifies three parameters only:

func main() {
	args := os.Args
	if len(args) != 2 {
		msg := fmt.Sprintf(&quot;Usage: %v &lt;path_to_directory&gt;&quot;, args[0])
		log.Fatal(msg)
	}

	fullPath := args[1]
	dirMap := make(map[string]uint32)

	filepath.WalkDir(fullPath, walk)

}

// how to create parameter accepting &amp;map[string]uint32
func walk(path string, entry fs.DirEntry, err error) error {
	if err != nil {
		return err
	}

	if !entry.IsDir() {
		// add entry and it&#39;s size to dirMap

		file, err := os.Stat(path)
		if err != nil {
			log.Println(&quot;Error determining file size:&quot;, err)
		}

		size := file.Size()

		// add path and size to dirMap

	} else if entry.IsDir() {
		// recurse here

	} else {
		log.Println(&quot;Unhandled branch:&quot;)
		log.Println(entry.Info())
	}

	return nil
}

EDIT: Since walk is a WalkDirFunc passed to filepath.walkDir, it is necessary to pass the map beginning here. In Python, I would use named parameters to accomplish this, but what is the best way in Go?

func main() {
	args := os.Args
    ...

	fullPath := args[1]
	dirMap := make(map[string]uint32)


	// dirMap should be passed here
	filepath.WalkDir(fullPath, walk)

}

答案1

得分: 3

使用一个闭包。将walk函数改为:

func walk(dirMap map[string]uint32, path string, entry fs.DirEntry, err error) error {
    ...
}

像这样调用WalkDir

dirMap := make(map[string]uint32)
filepath.WalkDir(fullPath, func(path string, entry fs.DirEntry, err error) error {
    return walk(dirMap, path, entry, err)
})

在这里运行示例:https://go.dev/play/p/rjV2rSBsUDz

英文:

Use a closure. Change walk to:

func walk(dirMap map[string]uint32, path string, entry fs.DirEntry, err error) error {
    ...
}

Call WalkDir like this:

dirMap := make(map[string]uint32)
filepath.WalkDir(fullPath, func(path string, entry fs.DirEntry, err error) error {
	return walk(dirMap, path, entry, err)
})

Run the example here: https://go.dev/play/p/rjV2rSBsUDz

huangapple
  • 本文由 发表于 2022年12月10日 01:17:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/74746318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定