1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go言語 再回帰

Posted at

再回帰とは、

関数自身から関数自身を呼び出す、無限入れ子です。
主に階層構造、フォルダーの検索によく使われます。

fileTools.go
import (
	"os"
	"path/filepath"
)

func findFiles(find string, dir string, deep int) ([]string, error) {
	var fulldir string
	var results []string

	fulldir, err := filepath.Abs(dir)
	if err != nil {
		return results, err
	}

	var _findFiles func(find string, dir string, deep int) ([]string, error)

	_findFiles = func(find string, dir string, deep int) ([]string, error) {
		var results []string

		fulldir, err := filepath.Abs(dir)
		if err != nil {
			return results, err
		}

		files, err := os.ReadDir(fulldir)
		if err != nil {
			return results, err
		}

		var childFind bool
		if deep != 0 {
			childFind = true
		}

		childDeep := deep
		if deep > 0 {
			childDeep--
		}

		for _, f := range files {
			fullName := filepath.Join(fulldir, f.Name())

			if f.IsDir() {
				if childFind {
					files, _ := _findFiles(find, fullName, childDeep)

					for i := range files {
						results = append(results, files[i])
					}
				}
			} else {
				if len(find) > 0 {
					if ok, _ := filepath.Match(find, f.Name()); ok {
						results = append(results, fullName)
					}
				} else {
					results = append(results, fullName)
				}
			}
		}

		return results, nil
	}

	results, err = _findFiles(find, fulldir, deep)
	if err != nil {
		return results, err
	}

	return results, nil
}

解説

Go言語では、関数の中に無名関数を宣言できます。
無名関数は、「func(引数)」のように関数名を宣言しません。

_findFiles = func(find string, dir string, deep int) ([]string, error) {...}

Go言語では、関数を呼び出すには、関数名が必要なため、関数を変数として先に宣言しておきます。

var _findFiles func(find string, dir string, deep int) ([]string, error)

再回帰は、無名関数の必要は無いが、今回のように親関数と子関数が異なる場合、子関数を独立させると、間違って子関数を使ってしまう場合があります。
公開したくない関数は、無名関数として埋め込んでしまいます。

この findFiles関数の使い方

引数1: find は、ワイルドカードが使えます。
 ※注意: "*.xlsx"は Excelファイルです。
引数2: dir は、検索したいパスです。
 ※注意: "../"は、現在の親フォルダーです。
引数3: deep は、-1:制限なし, 0:このフォルダーのみ, 1以上:深さ指定

main.go
func main() {
	files, err := findFiles("*.xlsx", "../", -1)
	if err != nil {
		return
	}

	for i := range files {
		fmt.Println(i, files[i])
	}
}

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?