Menu
Coddy logo textTech

구조체 임베딩 기초

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 35번째.

구조체 임베딩은 하나의 구조체 타입을 다른 구조체 안에 포함하기 위한 Go의 메커니즘입니다. 필드 이름을 사용하는 대신 타입만 지정하면 Go가 임베드된 구조체의 fields를 바깥쪽 구조체로 승격합니다.

기본 구문은 다음과 같습니다:

type Address struct {
    City    string
    Country string
}

type Person struct {
    Name string
    Address  // 임베디드 - 필드 이름 없음
}

AddressPerson에 임베드하면 외부 구조체에서 임베드된 fieldsdirectly access할 수 있습니다:

func main() {
    p := Person{
        Name: "Alice",
        Address: Address{
            City:    "London",
            Country: "UK",
        },
    }
    
    fmt.Println(p.City)     // London - 직접 접근
    fmt.Println(p.Country)  // UK - 직접 접근
    fmt.Println(p.Address.City)  // 이것도 작동함
}

p.Cityp.Address.City를 명시적으로 작성하지 않아도 작동하는 방식에 주목하세요. Go는 embedded 구조체의 fields를 자동으로 승격하여 마치 외부 구조체에 속한 것처럼 access할 수 있게 합니다. 필요할 때는 embedded type name을 통해 여전히 access할 수 있습니다.

이는 내부 fields에 access하기 위해 항상 field 이름을 사용해야 하는 일반적인 중첩 구조체와는 다릅니다. Embedding은 관련 데이터의 논리적 그룹화를 유지하면서도 더 평탄하고 편리한 API를 만들어 줍니다.

challenge icon

챌린지

쉬움

struct embedding을 사용하여 깔끔하고 체계적인 데이터 모델을 만드는 차량 등록 시스템을 구축해 보겠습니다. contact information과 vehicle details를 분리하면서 embedding을 통해 모든 fields에 direct access할 수 있도록 합니다.

코드를 두 파일에 걸쳐 구성합니다:

  • vehicle.go: embedding을 통해 함께 작동하는 두 개의 구조체를 생성합니다:
    • ContactInfo 구조체에 OwnerNamePhone fields를 추가합니다(둘 다 문자열).
    • ContactInfo를 field name 없이 embedded하는 Vehicle 구조체를 만들고, 자체 Make, Model, Year fields를 추가합니다.
    또한 VehicleSummary라는 method를 생성하여 모든 vehicle 및 contact information을 포함하는 formatted string을 반환하도록 합니다.
  • main.go: input에서 vehicle 및 owner details를 읽고, embedded ContactInfo가 포함된 Vehicle instance를 생성한 다음, embedded fields에 direct access하는 방법과 embedded type name을 통해 access하는 방법을 모두 보여 줍니다. 마지막에 vehicle summary를 출력합니다.

다음 input이 제공됩니다:

  • Line 1: Owner name
  • Line 2: Phone number
  • Line 3: Vehicle make
  • Line 4: Vehicle model
  • Line 5: Year (integer)

Summary method는 다음 format의 string을 반환해야 합니다:

[Year] [Make] [Model] - Owner: [OwnerName], Phone: [Phone]

main 파일에서 다음을 출력하여 field promotion을 보여 줍니다:

  1. Vehicle에서 direct access한 owner name(예: v.OwnerName)
  2. embedded type을 통해 access한 phone(예: v.ContactInfo.Phone)
  3. Summary method에서 반환된 전체 summary

예를 들어 Alice Smith, 555-1234, Toyota, Camry, 2023이 주어졌다면 output은 다음과 같아야 합니다:

Alice Smith
555-1234
2023 Toyota Camry - Owner: Alice Smith, Phone: 555-1234

두 access pattern이 모두 작동하는 방식을 확인해 보세요. 하나는 field promotion을 통한 direct access이고, 다른 하나는 embedded type name을 통한 explicit access이므로, embedded data를 다루는 방식에 유연성을 제공합니다.

직접 해보기

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// 소유자 이름 읽기
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)

	// 전화번호 읽기
	phone, _ := reader.ReadString('\n')
	phone = strings.TrimSpace(phone)

	// 차량 제조사 읽기
	make, _ := reader.ReadString('\n')
	make = strings.TrimSpace(make)

	// 차량 모델 읽기
	model, _ := reader.ReadString('\n')
	model = strings.TrimSpace(model)

	// 연도 읽기
	yearStr, _ := reader.ReadString('\n')
	yearStr = strings.TrimSpace(yearStr)
	year, _ := strconv.Atoi(yearStr)

	// TODO: 임베디드 ContactInfo가 있는 Vehicle 인스턴스 생성
	// 위에서 입력으로부터 읽은 값 사용

	// TODO: Vehicle에서 직접 접근한 소유자 이름 출력 (필드 프로모션)
	// 예: fmt.Println(v.OwnerName)

	// TODO: 임베디드 타입 이름을 통해 접근한 전화번호 출력
	// 예: fmt.Println(v.ContactInfo.Phone)

	// TODO: Summary 메서드를 사용하여 전체 요약 출력
	// 예: fmt.Println(v.Summary())

	// 솔루션을 구현한 후 이 줄들을 제거하세요
	_ = ownerName
	_ = phone
	_ = make
	_ = model
	_ = year
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Go 컴파일러