「Go/ファイル入出力」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
規約と慣習に従ったリファクタリング
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
defer で f.Close()
タグ: 2017年版ソースエディター
5 行
<code> os.Create </code> 関数の第1引数は、正常動作時の戻り値、第2引数はエラー時に nil 以外を返します。
 
;[https://play.golang.org/p/DzXKtvcf3ZR コード例]:<syntaxhighlight lang="go" line>
package main
 
import (
"log"
"os"
)
 
func main() {
f, err := os.Create("file-create-test.txt")
if err != nil {
log.Fatal(err)
}
}
defer f.Close()
if _, err := f.Write([]byte("TEST TEXT\n")); err != nil {
 
f.Close()
if _, err := f.Write([]byte("TEST TEXT\n")); err != nil {
log.Fatal(err)
}
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}
</syntaxhighlight>
; 解説 :<syntaxhighlight lang=go start=15 line>
: 13行目の fp.Write は[]byte(byte型のスライス)を引数にするので、明示的に型変換しています。
if if_, err := f.CloseWrite([]byte("TEST TEXT\n")); err != nil {
 
</syntaxhighlight>
もし、err が nil 以外の場合は
: 13行目の fp.Write は[]byte(byte型のスライス)を引数にするので、明示的に型変換しています。
log.Fatal(err)
; 遅延実行 :<syntaxhighlight lang=go start=13 line>
defer f.Close()
</syntaxhighlight>
: '''defer''' 遅延実行で、スコープを抜けるときに実行する処理を登録します。
: この場合は main関数を抜けるときに <code>f.Close()</code> が必ず実行されます。
: [[C++]]のディストラクターと似ていますが、オブジェクトに紐付いてはおらず複数の遅延実行の実行順を制御できるところが違います。
: [[C言語]]の at_exit()関数とも似ていますが、at_exit()はプログラムの終了のタイミングに実行されるのに対して、defer は関数やブロックのスコープを抜けたときに実行されます。
: 一旦 defer で登録処理を取り消す方法はありません。登録された処理側で条件判定する必要があります。
: Goでは goroutine もそうですが<ref>goroutine には、スレッドにありがちな kill や join はなく、チェンネルなどの通信を使って実現します。このため go 文には値がありません(スレッドならスレッドIDを返すところ)。</ref>、呼び出し先の生殺与奪の権を呼び出し元に握らせるのではなく、ある種の通信を行い協調して状態の遷移を管理するスタイルです。
; エラーハンドリング : <syntaxhighlight lang=go>
log.Fatal(err)
</syntaxhighlight>
をコールすると
:<syntaxhighlight lang=text>
2021/09/19 12:44:27 open file-create-test.txt: permission denied
exit status 1
</syntaxhighlight>
の様に診断メセージを書き出します。
 
== 脚註 ==
<references />
 
[[カテゴリ:Go]]