📦

変数と型 — Rubyの動的型付けが恋しくなる瞬間

ダックタイピングが消えた世界で生き残る

Rubyで変数を作る時、型を気にしたことがあるか?ない。name = "hello"でStringだ。name = 42に変えても誰も文句を言わない。ランタイムが勝手に処理する。

Goは違う。var name string = "hello" — 型を明示する。短く書くとname := "hello"だが、それでもGoコンパイラが型を推論して固定する。一度stringなら永遠にstring。name = 42はコンパイルエラー。

:= がRubyの = と違う点

Rubyの=は何でも再代入できる。Goの:=は宣言+初期化を一度にやるが、以後型は変えられない。Rubyでx = []; x = {}ができるのはGoでは不可能だ。

ゼロ値(Zero Value)— nilの代わり

Rubyで初期化していない変数はnil。Goでは型ごとにゼロ値が決まっている。intは0、stringは""、boolはfalse、ポインタはnil。Rubyのnil一つで統一される世界の方がシンプルに見えるかもしれない。

型変換が自動じゃない

Ruby: "count: " + 42.to_s。Go: "count: " + strconv.Itoa(42) — 明示的変換必須。intとfloat64の間も自動変換されない。面倒か?面倒だ。でもRubyで"5" + 3のTypeErrorをプロダクションで経験した人は、Goの厳格さがむしろ楽に感じるだろう。

RubyからGoへ

1

Ruby: 動的型付け、任意の値を再代入可能 → Go: 静的型付け、一度決めた型は変更不可

2

Ruby: nil一つで統一 → Go: 型別ゼロ値(int=0、string=""、bool=false)

3

Ruby: .to_s、.to_iで簡便変換 → Go: strconvパッケージで明示的変換必須

4

:= は宣言+初期化の省略形。関数内でのみ使用可能(パッケージレベルはvar必須)

メリット

  • コンパイル時に型エラーを全て捕捉 — Rubyの「本番で発見」パターンが消える
  • := 省略文法で型明示なしでも使用可能 — 思ったより面倒じゃない

デメリット

  • 型変換が全て明示的 — Rubyの.to_s一発に比べるとコードが長くなる
  • Genericが1.18でやっと追加 — 型システムが成熟していない部分がある

ユースケース

Rubyの動的型付けで発生するランタイム型エラーをコンパイル時に捕まえたい時 JSON APIレスポンスの型をstructで明示して安全にパースしたい時