GO · 구조체/인터페이스
임베딩과 구성 (Embedding & Composition)
Go는 상속 대신 구조체 임베딩으로 코드를 재사용합니다. 임베딩된 타입의 메서드가 자동으로 승격(promote)되어 외부 구조체에서 직접 호출할 수 있으며, 인터페이스도 임베딩하여 조합할 수 있습니다.
구조체/인터페이스중급embeddingcompositionstructinterfacepromotion
핵심 설명
Go는 상속 대신 구조체 임베딩으로 코드를 재사용합니다. 임베딩된 타입의 메서드가 자동으로 승격(promote)되어 외부 구조체에서 직접 호출할 수 있으며, 인터페이스도 임베딩하여 조합할 수 있습니다.
Go code
package main
import "fmt"
// 1. 구조체 임베딩 기초
type Logger struct {
Prefix string
}
func (l Logger) Log(msg string) {
fmt.Printf("[%s] %s\n", l.Prefix, msg)
}
func (l Logger) Error(msg string) {
fmt.Printf("[%s] ERROR: %s\n", l.Prefix, msg)
}
type Server struct {
Logger // 임베딩: Logger의 메서드가 승격됨
Host string
Port int
}
// 2. 메서드 오버라이드 (shadowing)
func (s Server) Log(msg string) {
// 원래 Logger.Log도 호출 가능
s.Logger.Log(fmt.Sprintf("%s:%d - %s", s.Host, s.Port, msg))
}
// 3. 인터페이스 임베딩
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
// Reader + Writer 조합
type ReadWriter interface {
Reader
Writer
}
// 4. 다중 임베딩
type Metrics struct {
RequestCount int
}
func (m *Metrics) IncrementRequests() {
m.RequestCount++
}
func (m Metrics) Report() string {
return fmt.Sprintf("요청 수: %d", m.RequestCount)
}
type APIServer struct {
Server // Logger 포함
*Metrics // 포인터 임베딩도 가능
Version string
}
func main() {
// 구조체 임베딩 사용
srv := Server{
Logger: Logger{Prefix: "WEB"},
Host: "localhost",
Port: 8080,
}
srv.Log("서버 시작") // Server.Log 호출 (오버라이드됨)
srv.Error("연결 실패") // Logger.Error 직접 승격
// 다중 임베딩
api := APIServer{
Server: srv,
Metrics: &Metrics{},
Version: "v2",
}
api.Log("API 요청 처리") // Server.Log → Logger.Log
api.IncrementRequests() // Metrics.IncrementRequests
api.IncrementRequests()
fmt.Println(api.Report()) // "요청 수: 2"
fmt.Printf("서버: %s:%d (%s)\n", api.Host, api.Port, api.Version)
}학습 팁
임베딩은 "has-a" 관계이지 "is-a" 관계가 아닙니다. 내부 타입의 메서드가 승격되지만, 다형성(polymorphism)은 인터페이스로 구현하세요.
주의할 점
두 임베딩된 타입에 같은 이름의 메서드가 있으면 컴파일 에러가 발생합니다. 이 경우 외부 구조체에서 명시적으로 어떤 임베딩의 메서드를 호출할지 지정해야 합니다.
자주 묻는 질문
임베딩과 구성 (Embedding & Composition)란 무엇인가요?
Go는 상속 대신 구조체 임베딩으로 코드를 재사용합니다. 임베딩된 타입의 메서드가 자동으로 승격(promote)되어 외부 구조체에서 직접 호출할 수 있으며, 인터페이스도 임베딩하여 조합할 수 있습니다.
임베딩과 구성 (Embedding & Composition) 학습 시 주의할 점은 무엇인가요?
두 임베딩된 타입에 같은 이름의 메서드가 있으면 컴파일 에러가 발생합니다. 이 경우 외부 구조체에서 명시적으로 어떤 임베딩의 메서드를 호출할지 지정해야 합니다.
Continue Learning
Go 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.