はじめに
RubyエンジニアがGoを学ぶ際、「こんなはずじゃなかった」と感じる瞬間が多々あります。
RubyとGoは哲学も設計思想も異なるため、同じタスクを実現するにも書き方やアプローチが大きく変わります。
本記事では、RubyとGoの具体的なコード例を比較しながら、どのように異なるかを解説します。解決策は置いておき、純粋に「つまずきポイント」を紹介します。
1. 型宣言の必要性
Rubyでは型を意識する必要がありませんが、Goでは型を明示する必要があります。これが書き始めのハードルになることも。
Ruby
def add(a, b)
a + b
end
result = add(1, "2") # 実行時エラー
Go
func add(a int, b int) int {
return a + b
}
// コンパイルエラー: "2"は文字列でintにできない
result := add(1, "2")
2. クラスがない
Rubyではクラスを使った設計が基本ですが、Goにはクラスがありません。構造体で代替する設計思想に戸惑うことが多いです。
Ruby
class User
attr_accessor :name
def initialize(name)
@name = name
end
def greet
"Hello, #{@name}!"
end
end
user = User.new("Alice")
puts user.greet
Go
type User struct {
Name string
}
func (u User) Greet() string {
return "Hello, " + u.Name + "!"
}
user := User{Name: "Alice"}
fmt.Println(user.Greet())
3. パッケージとファイル構造の厳格さ
Rubyではrequire
で好きな場所からコードを呼び出せますが、Goではパッケージ構造が厳密です。
Ruby
main.rb
require './utils'
puts Utils.say_hello
utils.rb
module Utils
def self.say_hello
"Hello from Utils"
end
end
Go
main.go
package main
import (
"fmt"
"myapp/utils"
)
func main() {
fmt.Println(utils.SayHello())
}
utils/utils.go
package utils
func SayHello() string {
return "Hello from Utils"
}
4. エラーハンドリングの煩雑さ
Rubyではbegin-rescue
構文でエラーを簡単に処理できますが、Goではエラーチェックが明示的です。
Ruby
begin
result = 1 / 0
rescue ZeroDivisionError => e
puts "Error: #{e.message}"
end
Go
result, err := divide(1, 0)
if err != nil {
fmt.Println("Error:", err)
}
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
おわりに
RubyとGoはどちらも強力な言語ですが、その違いによりエンジニアは新しい視点を得ることができます。本記事の具体例が、Rubyエンジニアの皆さんにとってGoの学習のヒントとなれば幸いです。