[[golang/逆引き]]

#contents

*目的 [#y172de97]
-ディレクトリを再帰的に辿って各ディレクトリやファイルに対して処理を行う。
-find コマンドの様なことをしたい。
-でも自分で再帰処理を書きたくない。

*やり方 [#v385f5b5]
os.File の Readdir 等を使って再帰的な関数を書けば出来るが標準パッケージにある [[path.Walk()>http://golang.org/pkg/path/]] を使うとシンプルに書けるらしい。

*サンプル [#y3ad404f]
:find1.go|
 package main
 
 import (
     "fmt";
     "path";
     "os";
 )
 
 type my_visitor struct{}
 
 func (v *my_visitor) VisitDir(path string, d *os.Dir) bool {
     fmt.Printf("d: %s\n", path);
     return true;
 }
 
 func (v *my_visitor) VisitFile(path string, d *os.Dir) {
     fmt.Printf("f: %s\n", path);
 }
 
 func main() {
     v := &my_visitor{};
     errors := make(chan os.Error);
     path.Walk("/etc/httpd", v, errors);
 }
:実行結果|
 d: /etc/httpd
 d: /etc/httpd/conf
 f: /etc/httpd/conf/httpd.conf
 f: /etc/httpd/conf/magic
 d: /etc/httpd/conf.d
 f: /etc/httpd/conf.d/README
 f: /etc/httpd/conf.d/mod_dnssd.conf
 f: /etc/httpd/conf.d/php.conf
 f: /etc/httpd/conf.d/proxy_ajp.conf
 f: /etc/httpd/conf.d/welcome.conf
 f: /etc/httpd/logs
 f: /etc/httpd/modules
 f: /etc/httpd/run

**説明 [#xd3c4e17]
-path.Walk は以下のような定義になっていて、
 func Walk(root string, v Visitor, errors chan<- os.Error)
-Visitor という以下のようなインターフェースを引数に取る。
 type Visitor interface {
     VisitDir(path string, d *os.Dir) bool;
     VisitFile(path string, d *os.Dir);
 }
-サンプルでは、見つかったpathをprintするだけの my_visitor という型を定義してそれを渡している。
--Go言語ではインターフェースのメソッドと同じシグニチャのメソッドが定義された型を作ってやればそのインターフェースを実装したことになるらしい。
--なので、ここでは my_visitor は値を何も持たない型だがとりあえず定義して、VisitDirとVisitFileというメソッドを定義してみた。
--何も値を持たない型だがとりあえず適当にnewしてやる。
--ついでにos.Errorを受け取る為のチャンネルも必要なようなので適当にmakeしてやる。
--で、vとerrorsを渡してやったら動いたようだ(^^;
-Visitorを実装した型の変数を渡してやれば良いだけなので、別にnewはしなくても良いようだ。
 //↓こんな風にしても動いた。
 var v *my_visitor;
 path.Walk("/etc/httpd", v, errors);


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS