「Go言語って何ででこんなに偏屈なんだろう」より
まぁ「偏屈」かどうかは主観の問題なので敢えて異を唱えたりはしないけど,この筆者,多分 Go 言語を全く触ってないな(笑)
nullじゃなくてnil
誤解されやすいが Go 言語は「「コンパイル速度を上げる」目的で作った言語」ではない。
結果的に速いコードを生成することが多いが,再帰処理など効率が悪くなる局面もある。 ただしメモリリーク等の「脆弱性」の発生にはかなり配慮していると言える。
そのひとつのあらわれがポインタの扱い。
名前の好みはどうしようもないけど, Java や C/C++ の null/NULL との違いを言うと
nil は事実上の「null 参照」である
nil は型(type)を持つ
という点。
Go 言語では原則としてポインタ演算がない(例外は unsafe パッケージを使う場合)。
なので nil は事実上の「null 参照」と言える(null 参照を許容することの是非は今は横に置いておく)。
更に「nil は型を持つ」というのは nil が単なる「値」ではなく状態を持つオブジェクトであることを示す。
なんで、func int f()じゃなく、func f() intなのか
関数宣言に限らず型の指定は後置で統一されている。
これは型指定が省略可能だからだ(もちろん構文によって省略できない場合もある)。
その代り Go 言語には void 型というのは存在しない(これに関連して Generics もない。 Generics についてはコミュニティ内でも強い要望があるが実現は難しそうである)。
単に省略されるだけ。
あと,リテラル記述やメソッドレシーバとの組み合わせで考えると,なおさら前置はありえない。
var hoge int は不可解
var キーワードは変数の宣言に必須。
たとえば以下のように記述できる。
code:go
var (
ErrInvalid = errors.New("invalid argument")
ErrPermission = errors.New("permission denied")
ErrExist = errors.New("file already exists")
ErrNotExist = errors.New("file does not exist")
)
例外は関数内で := トークンを使って宣言する場合。
var, const, func といったキーワードは宣言ステートメントの開始を指すものだと思えばいいだろう。
他の言語では宣言の記述を省略できるものがあるけど, Go 言語はそうしなかったということになる。
宣言の明示はバグの軽減という意味でメリットがあると私は思うが,この辺は人によるかなぁ。
まだいろいろある
ゼロ除算やヒープエラーなどに対しては panic が投げられる。
panic を recover で拾う(つまり例外処理のように使う)ことはできるが,普通はしない。
panic が投げられるような状態ならプロセスを継続すべきではないことが殆んどだからだ。
ゼロ除算が発生しうるような事象があるならそれは予測可能なバグでありゼロ除算が発生する前に回避すべき,というのが Go 言語の基本思想。
もちろん Java の「検査例外」のようなものは存在しない。 error のハンドリングや panic のハンドリングは Go 言語のポイントのひとつなので是非習得していただきたいところ。
Go 言語のエラーハンドリングに慣れると Java や C/C++ 等の「例外処理」がウザくてたまらなくなる(笑)
ブックマーク