Menu
Coddy logo textTech

Map 값으로 포인터 사용하기

Coddy GO 여정의 로직 & 흐름 섹션에 포함된 레슨 — 68개 중 27번째.

구조체를 맵에 직접 저장하는 것도 유용하지만, 구조체에 대한 포인터를 저장하면 강력한 기능을 활용할 수 있습니다. 바로 맵을 통해 원본 구조체 데이터를 직접 수정할 수 있는 기능입니다. 이 방식은 데이터를 저장한 후에 업데이트해야 할 때 필수적입니다.

구조체에 대한 포인터를 맵의 값으로 저장할 때, 구조체의 복사본이 아니라 구조체의 메모리 주소를 저장하는 것입니다. 이러한 맵을 선언하고 사용하는 방법은 다음과 같습니다:

type Product struct {
    Price    float64
    Quantity int
}

products := map[string]*Product{
    "laptop": &Product{Price: 999.99, Quantity: 5},
    "mouse":  &Product{Price: 25.50, Quantity: 20},
}

데이터를 수정해야 할 때 주요 장점이 명확해집니다. 포인터를 사용하고 있기 때문에, 맵을 통해 변경한 사항이 원래의 구조체에 영향을 미칩니다:

// 맵을 통해 직접 노트북의 가격을 업데이트합니다
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // 출력: 899.99

이 패턴은 재고 시스템, 사용자 프로필 또는 맵이 기본 데이터 저장소 역할을 하고 수정 사항이 유지되어야 하는 시나리오와 같이, 저장된 데이터를 빈번하게 업데이트해야 하는 애플리케이션에서 특히 유용합니다.

challenge icon

챌린지

쉬움

구조체 포인터를 맵의 값으로 사용하는 강력한 기능을 보여주는 간단한 재고 관리 시스템을 구축해 보세요. 이 챌린지는 포인터 기반 맵이 저장된 데이터를 직접 수정할 수 있게 하여, 재고 시스템을 효율적이고 업데이트에 민첩하게 만드는 방법을 보여줍니다.

세 가지 입력을 받게 됩니다:

  • 제품 수를 나타내는 문자열 (예: "4")
  • "name1:price1:quantity1,name2:price2:quantity2,name3:price3:quantity3" 형식의 제품 데이터를 포함하는 문자열 (예: "laptop:999.99:5,mouse:25.50:20,keyboard:75.00:15,monitor:299.99:8")
  • "operation1:product1:value1,operation2:product2:value2" 형식의 업데이트 작업을 포함하는 문자열. 여기서 작업은 "price" 또는 "quantity" 중 하나입니다 (예: "price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")

여러분의 과제는 다음과 같습니다:

  1. 다음 필드를 가진 Product 구조체를 정의합니다:
    • Price (float64) - 제품 가격
    • Quantity (int) - 제품 재고 수량
  2. 키는 제품 이름(문자열)이고 값은 Product 구조체에 대한 포인터인 맵을 생성합니다.
  3. 두 번째 입력에서 제품 데이터를 파싱합니다:
    • 입력을 쉼표로 나누어 개별 제품 항목을 가져옵니다.
    • 각 항목을 콜론으로 나누어 이름, 가격, 수량을 분리합니다.
    • 가격 문자열을 float64로, 수량 문자열을 정수로 변환합니다.
    • Product 구조체를 생성하고 맵에 해당 구조체의 포인터를 저장합니다.
  4. "Initial Inventory:"라는 헤더와 함께 초기 재고를 표시합니다.
  5. 각 제품을 "[name]: $[price] (Stock: [quantity])" 형식으로 표시합니다.
  6. 세 번째 입력에서 업데이트 작업을 파싱하고 적용합니다:
    • 입력을 쉼표로 나누어 개별 작업을 가져옵니다.
    • 각 작업을 콜론으로 나누어 작업 유형, 제품 이름, 새 값을 가져옵니다.
    • 맵 포인터를 통해 해당 필드를 직접 업데이트합니다.
    • 각 업데이트를 "Updated [product]: [field] changed to [new_value]" 형식으로 출력합니다.
  7. "Updated Inventory:"라는 헤더와 함께 업데이트된 재고를 표시합니다.
  8. 초기 표시와 동일한 형식으로 각 제품을 다시 표시합니다.
  9. 총 재고 가치를 계산하고 표시합니다: "Total Inventory Value: $[total_value]"

가격 및 수량 문자열을 각각의 숫자 유형으로 변환하려면 strconv 패키지를 사용하세요. 표시할 때 모든 가격은 소수점 이하 2자리까지 형식을 맞춥니다. 이 챌린지는 맵에 포인터를 저장함으로써 맵에 값을 다시 할당할 필요 없이 원본 구조체 데이터를 직접 수정하여 재고 업데이트를 즉각적이고 영구적으로 만드는 방법을 보여줍니다.

직접 해보기

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	// 입력 읽기
	var numProductsStr string
	var productDataStr string
	var operationsStr string
	
	fmt.Scanln(&numProductsStr)
	fmt.Scanln(&productDataStr)
	fmt.Scanln(&operationsStr)
	
	// TODO: 여기에 Product 구조체 정의
	
	// TODO: 제품 포인터를 저장할 맵 생성
	
	// TODO: 제품 순서를 유지하기 위한 슬라이스 생성 (일관된 출력을 보장하기 위함)
	
	// TODO: 제품 데이터를 파싱하고 맵에 채우기
	// 기억할 사항:
	// - productDataStr를 쉼표로 분할하여 개별 항목 가져오기
	// - 각 항목을 콜론으로 분할하여 이름, 가격, 수량 가져오기
	// - 가격 및 수량 문자열을 적절한 타입으로 변환
	// - 맵에 Product 구조체 포인터 저장
	// - 순서 슬라이스에 제품 이름 추가
	
	// TODO: 초기 재고 표시
	// 순서 슬라이스를 사용하여 제품을 일관되게 반복
	// 형식: "[name]: $[price] (Stock: [quantity])"
	
	// TODO: 업데이트 작업 파싱 및 적용
	// 기억할 사항:
	// - operationsStr를 쉼표로 분할하여 개별 작업 가져오기
	// - 각 작업을 콜론으로 분할하여 유형, 이름, 값 가져오기
	// - 맵 포인터를 통해 해당 필드를 직접 업데이트
	// - 각 작업에 대한 업데이트 메시지 출력
	
	// TODO: 업데이트된 재고 표시
	// 다시 한 번, 일관된 출력을 위해 순서 슬라이스 사용
	// 표시하면서 총 가치 계산
	
	// TODO: 총 재고 가치 계산 및 표시
	// 형식: "Total Inventory Value: $[total_value]"
}
quiz icon실력 점검

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

로직 & 흐름의 모든 레슨