# 가끔 Go는 No-Go가 되어야 합니다

> Clean Markdown view of GeekNews topic #18276. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=18276](https://news.hada.io/topic?id=18276)
- GeekNews Markdown: [https://news.hada.io/topic/18276.md](https://news.hada.io/topic/18276.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-12-16T09:26:24+09:00
- Updated: 2024-12-16T09:26:24+09:00
- Original source: [brainbaking.com](https://brainbaking.com/post/2024/12/why-go-should-sometimes-be-a-no-go/)
- Points: 10
- Comments: 5

## Summary

저자는 Go 언어의 단순함이 장점이 될 수 있지만, 반복 작업과 기본 기능 부족으로 인해 생산성과 코드 가독성을 떨어뜨릴 수 있다고 지적합니다. 또한, Go의 철학이 클린 코드 원칙에 반할 수 있으며, 다양한 구현 방식과 논쟁을 유발한다고 설명합니다. Go는 인프라 개발에는 적합하지만, 복잡한 엔터프라이즈 응용 프로그램에는 부적합하다는 결론을 내립니다.

## Topic Body

- 저자가 Go 언어를 수년간 사용한 후 Java로 전환하게 되면서 느낀 Go 언어의 한계점과 문제점을 설명하는 글  
- Go가 단순하고 지루한(boring) 언어라는 특징이 장점이 아닌 단점이 될 수 있다는 관점을 제시함  
- Go의 철학: Google의 Go 설계 팀은 단순함과 제한성을 강조했지만, 이는 사용자가 직접 해결해야 하는 반복 작업을 야기함  
  
### 1. Go는 "재미없다"는 점이 **단점**일 수 있음  
- **Russ Cox의 주장**:  
  - Go는 "재미없다(boring)"는 점이 장점이라고 강조  
  - 루프는 `for` 하나뿐이며, 필터, 맵, 리듀스 같은 기능은 기본 제공되지 않음  
  - 대부분의 다른 언어에서 제공하는 다양한 고급 기능이 없는 것이 단순함의 일부로 간주됨  
- **Reddit 사용자 의견**:  
  - "재미없음"과 "강력함"의 경계가 모호  
  - Go의 기본 기능 부족은 언젠가 언어에 추가될 가능성이 높다고 주장  
- **서드파티 패키지 의존**:  
  - 부족한 기능을 보완하기 위해 자주 사용하는 `samber/lo` 패키지:  
    - 필터, 맵, 검색 등의 필수 기능 포함  
    - GitHub에서 18.1k 스타를 받고, 12.6k 이상의 프로젝트에서 사용  
  - 일부 기능은 `slices` 패키지로 추가되었으나 여전히 기능적으로 부족함  
- **작성자의 불만**:  
  - 반복적인 루프 작성 강요  
  - 필터 및 맵과 같은 작업을 간결하게 처리하기 어려움  
  - 별도의 리시버 메서드로 추출할 수는 있지만, 코드의 깔끔함을 저해  
- Go의 단순함은 많은 경우 장점이지만, 기본적인 편의 기능 부족은 생산성과 코드 가독성을 떨어뜨리는 단점이 될 수 있음  
  
### 2. **Clean Code 원칙을 방해함**  
- **에러 처리 문제**:  
  - 함수에서 반환 값으로 `error`를 포함하는 경우가 대부분:  
    - `if err != nil` 패턴을 반복적으로 사용해야 함  
    - 코드 정리 과정에서 오히려 코드가 더 복잡해지는 문제 발생  
  - HTTP 핸들러 코드가 간단한 프로젝트에서도 20줄 이상으로 증가  
    - 원래 목표는 4줄 정도로 유지  
  - `panic()`과 복구 미들웨어를 고려할 정도로 에러 처리 방식에 좌절  
- **짧은 이름 권장**:  
  - 변수, 메서드, 함수 이름에 짧은 이름 사용 권장:  
    - `c`, `a` 같은 이름이 무엇을 의미하는지 불명확  
    - 예: `c`는 Command, Controller, Argument, Amendment 중 무엇인가?  
    - 긴 이름을 사용하면 더 명확해질 수 있지만, Go의 철학은 짧은 이름을 선호  
  - 이로 인해 팀 코드 리뷰 중 테스트 메서드 이름 등에 대한 끝없는 논쟁 유발  
- Go의 철학은 코드의 간결함과 단순함을 강조하지만, 결과적으로 클린 코드 원칙에 반하는 복잡성과 비효율성을 초래할 수 있음  
  
### 3. **의도적으로 작은 언어 철학과 DIY 문화**  
- **기본 기능 부족**:  
  - 간단한 HTTP 핸들러를 구현하는 것은 쉽지만, 기본 미들웨어(예: 지수 백오프, 교차 사이트 설정 등)가 필요할 경우 여러 패키지를 찾아야 함  
  - 이러한 패키지들이 (1) 유지보수되고 있는지, (2) 기대대로 작동하는지 확신하기 어려움  
- **반복 작업 증가**:  
  - 단순함을 유지하려는 Go의 설계 철학이 오히려 개발자에게 "바퀴를 재발명"하라는 요구로 이어짐  
  - 예: 간단한 필터 기능조차 직접 구현해야 하는 상황 발생  
- **미성숙한 패키지 생태계**:  
  - 많은 GitHub 프로젝트가 방치되거나 소수 버전만 릴리스된 상태  
  - 상대적으로 젊은 언어라는 점에서 .NET/Java와 비교가 불공정할 수 있지만, 현실적으로 Go의 패키지 안정성과 성숙도가 부족함  
- **ORM의 한계**:  
  - Go의 주요 ORM 패키지(Gorm)는 Hibernate나 Entity Framework에 비해 기능적으로 뒤처짐  
  - 이상한 동작과 문서화 부족 문제 존재  
  - Go 커뮤니티의 반응: "Go에선 ORM이 필요 없음, Do It Yourself!"  
- Go의 단순성은 프로젝트와 팀에 따라 장점일 수 있지만, 기본 제공되지 않는 기능의 부족은 생산성과 개발 경험에 부정적인 영향을 미칠 수 있음.  
  
### 4. **Go에서 하나의 방식만 존재하지 않음**  
- **일관성과 통일성의 오해**:  
  - 테이블 테스트(Table Test)  
    - `stretchr/testify`와 같은 테스트 스위트 사용 (557k 프로젝트에서 사용 중)  
    - 테이블 테스트 내의 커스텀 서브테스트 작성  
  - 이로 인해 "통일된 방식"이라는 Go의 철학과 현실 사이에 괴리가 있음  
- **팀 내 갈등 유발**:  
  - 팀 간 테스트 스타일 및 구현 방식에 대한 논의가 오히려 증가  
  - Go의 철학과 설계 팀 자체도 일관성이 부족:  
    - 예: Getter 메서드 네이밍에 대한 불일치  
- **기능 거부와 패키지 의존**:  
  - Go 팀은 어서션(assertion) 기능 추가를 거부하며, 프로그래머의 부족함을 문제로 삼는 태도 비판받음  
  - 결과적으로 필요한 기능을 사용하기 위해 또 다른 패키지를 설치(`go get`)해야 함  
- Go는 단순성과 통일성을 지향하지만, 실제로는 다양한 구현 방식과 이에 따른 논쟁이 존재하며, 언어 설계 철학의 모호함이 문제를 악화시키고 있음  
  
### 5. **Go의 디버깅은 재미없음**  
- **디버깅 중 표현식 평가 불가**:  
  - 디버깅 세션에서 표현식을 평가하거나 객체의 커스텀 문자열 표현을 확인할 수 없음  
  - 런타임에 객체 상태를 명확히 파악하기 어려움  
- **스택트레이스와 로그의 비직관성**:  
  - 대규모 테스트(예: CI에서 수천 개 테스트 실행) 실패 시 혼란스러운 스택트레이스 및 로그 제공  
  - 결과적으로 디버깅이 어려워지고 생산성이 저하됨  
- **C 스타일 디버깅 경험**:  
  - Go의 디버깅 도구 체인이 C 기반으로 동작:  
    - C와 유사한 원시적 디버깅 경험 제공  
    - 개발자 친화적이지 않음  
- **Rust와의 비교**:  
  - Rust는 Go의 한계를 개선:  
    - 명확하고 유용한 에러 정보를 제공  
    - 에러 메시지에 정확한 수정 제안 포함  
- Go의 디버깅 경험은 최적화된 바이너리 제공에 중점을 둔 설계 철학에 기반하나, 이는 개발자 경험을 희생시키는 결과를 초래함. 디버깅 효율성을 중시하는 환경에서는 대안 언어를 고려하는 것이 바람직할 수 있음  
  
### 요약: Go의 적합성과 한계  
- **Go 내장 도구의 장점**:  
  - 패키지 관리, 테스트, 성능 모니터링을 위한 기본 도구 체인 제공  
  - 별도 설정 없이 사용 가능하여 초기 개발 환경 설정 간소화  
- **한계**:  
  - **"지루한 코드"와 반복 작업**:  
    - Go의 도구 체인은 기능적이지만, 코드 작성 시 반복 작업(Plumbing Code)을 강요  
    - 예: 단조로운 구문과 제한된 기능이 작업 흥미를 떨어뜨림  
  - **"import cycle not allowed"**:  
    - 테스트에서 순환 의존(import cycle)을 허용하지 않음  
    - 도메인 주도 설계(DDD) 작업 시 구조적 제약으로 인해 복잡도 증가  
  - **`struct` 임베딩 기법의 의존성**:  
    - 이상하고 제한적인 `struct` 임베딩 메커니즘으로 인한 사용상의 고통  
- **적합한 활용 영역**:  
  - 인프라스트럭처 개발에 적합:  
    - Docker, Drone, Hugo 등 시스템 수준의 툴이 Go로 작성됨  
  - 경량 서버 및 CLI 애플리케이션 개발에 유용  
- **부적합한 활용 영역**:  
  - 복잡한 엔터프라이즈 응용 프로그램(예: ERP 시스템) 개발:  
    - 제한된 언어 철학과 도구로 인해 대규모 비즈니스 로직 관리 비효율  
- Go는 특정 작업(특히 인프라 관련)에서는 뛰어난 효율을 제공하지만, 복잡한 비즈니스 도메인 애플리케이션에는 적합하지 않은 도구임. CTO가 구글 기술 스택에 치우친 경우에도 기술 선택에 신중해야 함

## Comments



### Comment 32478

- Author: secret3056
- Created: 2024-12-17T14:07:09+09:00
- Points: 1

Rust의 `?`만 있었어도 지금보다는 훨씬 낫지 않았을까요...

### Comment 32464

- Author: bbulbum
- Created: 2024-12-17T10:09:01+09:00
- Points: 1

Go 를 쓰면서 느낀점은, 그동안 얼마나 암묵적인 에러핸들링을 하고있었나 하고 생각이 들더라구요.  
물론 에러핸들링을 한 포인트에서 처리하는 것이 구조적으로 깔끔하게 보일 수 있겠지만, 명시적으로 에러응답이 가능한 동작임을 드러내면서 더 안전한 방식으로 코드를 만들게 되는 것 같다는 생각이 듭니다.

### Comment 32443

- Author: tsboard
- Created: 2024-12-16T17:52:26+09:00
- Points: 2

if err != nil {} 이거는 솔직히 좀 귀찮긴 합니다. 지적된 단점들도 동의하구요. 그래도 이 언어가 지향하는 바를 명확히 이해하고 어떤 점을 더 활용할지 고민한다면 지적된 단점에도 불구하고 더 잘 활용 할 수 있을 것 같습니다. C랑 비슷한데 GC가 있고, 제한적이지만 제네릭까지 지원되는데다 크로스 컴파일까지 된다! 이렇게 보면 또 혜자스러운 언어가 아닐까요?

### Comment 32416

- Author: riki3
- Created: 2024-12-16T12:47:30+09:00
- Points: 1

자바에서 go로 넘어가면서 처음엔 비슷한 느낌을 받았던 것 같네요.  
지금은 자바에 사용한 시간이 아깝다고 생각할 정도로 go를 즐기고 있습니다. 복잡한 비즈니스 어플리케이션에 적합하지 않다는건 그 어플리케이션이 시스템을 단순화하는데 충분히 고민하지 않았다라는 생각이 들게 만듭니다.

### Comment 32368

- Author: neo
- Created: 2024-12-16T09:26:24+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=42415566) 
- Java 개발자가 Go에 Java 스타일을 강요하면 문제가 발생함
  - Go 철학은 단기적으로는 덜 유용하지만, 장기적으로는 큰 차이를 만듦
  - JVM 생태계에 깊이 빠진 사람들은 Go를 즐기기 어려움

- 많은 개발자들이 너무 이른 추상화를 시도함
  - 간단한 반복이 충분할 때 불필요한 추상화를 만듦

- Go의 표준 라이브러리는 크지만 모든 것을 할 수 있을 만큼 크지는 않음
  - 프로젝트마다 바퀴를 재발명하는 경향이 있음
  - Go는 서버/CLI 애플리케이션에 이상적임

- 프로그래밍 언어 선택보다 더 큰 도전 과제가 존재함
  - Go의 메커니즘과 철학에 적응하는 것이 중요함

- Go를 좋아하는 이유를 이해하기 어려움
  - 언어 자체보다는 도구 체인과 배포의 용이함을 선호함

- Go의 핵심 팀이 잘못된 결정을 되돌리는 것이 좌절감을 줌
  - 좋은 패키지 시스템과 도구가 존재함
  - 복잡한 ERP 시스템에는 Java가 더 나은 선택일 수 있음

- Go는 UNIX와 같은 문제를 가짐
  - 복잡성을 사용자에게 떠넘기는 경향이 있음
  - Java의 런타임은 Go에 비해 빠르게 발전하고 있음
