hokita / 課題1 - #5
Conversation
|
こちらレビューお願いいたします。 |
| "path/filepath" | ||
| ) | ||
|
|
||
| func converterFactory(from string, to string) (*Converter, error) { |
| "path/filepath" | ||
| ) | ||
|
|
||
| func converterFactory(from string, to string) (*Converter, error) { |
| func (conv *Converter) Execute(path string) error { | ||
| // ignore unrelated file | ||
| if !conv.fromImage.IsMatchExt(filepath.Ext(path)) { | ||
| return nil |
There was a problem hiding this comment.
これだと成功したのか失敗したのか無視されたのか分かりづらいので、エラーを返して、呼び出し元で判断してもらうのが良さそうですね。たとえば、os.IsNotExist関数とかみたいにエラーを判定する関数があると良いかも知れないです。
(この辺はエラー処理の章でやります!)
|
|
||
| // output file | ||
| out, err := os.Create(conv.SwitchExt(path)) | ||
| defer out.Close() |
There was a problem hiding this comment.
os.Createのエラー処理の後で、defer文でCloseをしてください。
Closeメソッドもエラーを返すので、書き込みの場合のみエラー処理をお願いします。
コマンドラインツールの章のスライドにやり方は書いてあるので確認してみてください!
There was a problem hiding this comment.
書き込みの場合では Close がエラーを返す可能性があるんですね。
勉強になりました🙇
| } | ||
|
|
||
| // output image | ||
| conv.toImage.Encode(out, img) |
| from = flag.String("from", "jpg", "Conversion source extension.") | ||
| to = flag.String("to", "png", "Conversion target extension.") | ||
| ) | ||
| flag.Parse() |
There was a problem hiding this comment.
mainパッケージ以外でflagパッケージに依存させない(明示的に*flag.FlagSetを保つ場合を除く)。
flagパッケージやos.Argsに依存すると、コマンドラインツールありきのパッケージになってしまいます。
|
|
||
| type JpegImage struct{} | ||
|
|
||
| func (_ JpegImage) Encode(w io.Writer, m image.Image) error { |
| } | ||
|
|
||
| func (_ JpegImage) Extensions() []string { | ||
| return []string{".jpg", ".jpeg", ".JPG", ".JPEG"} |
There was a problem hiding this comment.
mapの方がいいのと、メソッドを呼び出すたびに生成する必要はないのでパッケージ変数にしても良さそうです
| ) | ||
|
|
||
| const ( | ||
| ExitCodeOk int = iota |
There was a problem hiding this comment.
iotaは値に意味がなく、区別が付けばいいときのみに使います。
そのため、0が成功、それ以外が失敗となっている終了コードに使わない方が良いでしょう。
| return &Converter{fromImage, toImage}, nil | ||
| } | ||
|
|
||
| var ErrUnmatchExt = errors.New("ext does not match") |
There was a problem hiding this comment.
IsNotMatchExt関数が公開されているのでこちらは公開しないほうが良いです。
|
|
||
| // file open | ||
| file, err := os.Open(path) | ||
| defer file.Close() |
|
|
||
| // output file | ||
| out, err := os.Create(conv.SwitchExt(path)) | ||
| defer func() { |
|
|
||
| type ImageType interface { | ||
| Encode(w io.Writer, m image.Image) error | ||
| IsMatchExt(ext string) bool |
There was a problem hiding this comment.
Hasとかぐらいでいい気もしますね。
pngImage.Has(ext)とかになると思うので。
長くてHasExtとか。
| type ImageType interface { | ||
| Encode(w io.Writer, m image.Image) error | ||
| IsMatchExt(ext string) bool | ||
| GetMainExt() string |
| } | ||
|
|
||
| func selectImage(ext string) (ImageType, error) { | ||
| pngImage := PngImage{} |
There was a problem hiding this comment.
フィールドの初期化を伴わない構造体リテラル(コンポジットリテラル)での初期化は不要です。
構造体もゼロ値で初期化されるため、var pngImg PngImageのように変数を定義されば十分です。
| } | ||
|
|
||
| err = filepath.Walk(dir, | ||
| func(path string, info os.FileInfo, err error) error { |
|
|
||
| const QUALITY = 100 | ||
|
|
||
| type JpegImage struct{} |
There was a problem hiding this comment.
JPEGで十分だと思います。Goでは略語はすべて大文字か全部小文字にします。
| "io" | ||
| ) | ||
|
|
||
| const QUALITY = 100 |
There was a problem hiding this comment.
定数であってもキャメルケースで書きます。
先頭が大文字だとパッケージ外に公開されます。
There was a problem hiding this comment.
JPEGのQUALITYっていうのが分かるようにしたほうが良さそうですね。
課題 1 画像変換コマンドを作ろう
課題内容
次の仕様を満たすコマンドを作って下さい
以下を満たすように開発してください
対応したこと
動作
$ go build -o test_imgconv $ ./test_imgconv -h Usage of ./test_imgconv: -from string Conversion source extension. (default "jpg") -to string Conversion target extension. (default "png") # testdata内のすべてのjpgファイルをpngに変換する $ ./test_imgconv testdata Conversion finished! # testdata内のすべてのpngファイルをjpgに変換する $ ./test_imgconv -from png -to jpg testdata Conversion finished! # ディレクトリの指定が無い場合はエラー $ ./test_imgconv Please specify a directory. # 存在しないディレクトリの場合はエラー $ ./test_imgconv non_exist_dir Cannot find directory. # 対応していない拡張子の場合はエラー $ ./test_imgconv -from txt -to jpg testdata Selected extension is not supported.工夫したこと
image_typeというinterfaceを作ってみた。わからなかったこと、むずかしかったこと