⚙️

함수와 메서드 — 클래스가 없는 세계의 메서드

Ruby의 def는 클래스 안에 산다. Go의 func는 struct에 붙는다.

Ruby에서 메서드를 만들면 항상 어떤 클래스 안에 있다. class User; def name; end; end — 메서드는 클래스의 것이다.

Go에서는 함수가 기본이다. func add(a, b int) int { return a + b } — 어떤 타입에도 속하지 않는 독립 함수. Ruby에서 이런 건 모듈 함수(module_function)로 만들지만, Go에서는 이게 기본이다.

메서드 = 리시버가 있는 함수

Go의 메서드는 "리시버"가 붙은 함수일 뿐이다:

type User struct { Name string }
func (u User) Greet() string { return "Hi, " + u.Name }

(u User) 부분이 리시버. Ruby로 치면 self가 명시적으로 선언된 거다. Ruby에서는 def greet; "Hi, #{name}"; end에서 self가 암묵적이다.

다중 반환값

Ruby에서 여러 값을 반환하려면 배열로 묶는다: return [value, error]. Go는 문법 레벨에서 다중 반환을 지원한다: func divide(a, b float64) (float64, error). 이게 Go의 에러 처리 패턴의 기반이다.

가변 인자

Ruby의 def sum(*numbers) → Go의 func sum(numbers ...int) int. 문법은 다르지만 개념은 같다. 다만 Go에서 ...은 타입 앞에 오고, Ruby에서 *는 파라미터 앞에 온다.

일급 함수

Ruby에는 Proc, Lambda, 블록이 있다. Go에도 일급 함수가 있다 — 변수에 함수를 할당할 수 있고, 함수를 인자로 넘길 수 있다. 다만 Ruby의 블록처럼 암묵적으로 넘기는 문법은 없다. 항상 명시적이다.

Ruby에서 Go로

1

Ruby: class 안에 def → Go: 독립 func + struct에 리시버로 메서드 부착

2

Ruby: return [a, b] → Go: 다중 반환값이 문법 레벨에서 지원 (f64, error)

3

Ruby: *args → Go: ...int (가변 인자, 문법만 다름)

4

Ruby: Proc/Lambda/Block → Go: 일급 함수 있지만 블록 문법 없음

장점

  • 리시버 문법으로 self가 명시적 — 어떤 타입의 메서드인지 한눈에 보인다
  • 다중 반환값으로 에러 처리가 자연스럽다 — 예외(exception) 없이도 에러 전파 가능

단점

  • 클래스 상속이 없어서 Ruby의 < 상속 패턴을 struct 임베딩으로 대체해야 한다
  • Ruby의 블록/yield 패턴이 없어서 DSL 스타일 코드를 작성하기 어렵다

사용 사례

Ruby의 클래스 기반 설계를 Go의 struct + 메서드 패턴으로 전환할 때 에러 처리에서 다중 반환값 패턴을 이해하고 활용해야 할 때

참고 자료