Menu
Coddy logo textTech

Map 값으로 포인터 사용하기

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

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

구조체에 대한 pointer를 map 값으로 저장하면 구조체의 복사본이 아니라 구조체의 메모리 주소를 저장하게 됩니다. 이러한 map을 선언하고 사용하는 방법은 다음과 같습니다.

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},
}

데이터를 수정해야 할 때 핵심적인 장점이 분명해집니다. 포인터를 사용하고 있으므로 map을 통해 변경한 내용이 원래 struct에 영향을 줍니다:

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

이 패턴은 저장된 데이터를 자주 업데이트해야 하는 애플리케이션, 예를 들어 Inventory 시스템, 사용자 프로필 또는 map이 기본 데이터 저장소로 사용되고 변경 사항을 유지해야 하는 모든 시나리오에서 특히 유용합니다.

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")
  • 다음 형식의 업데이트 operations가 포함된 문자열: "operation1:product1:value1,operation2:product2:value2" 여기서 operations는 "price" 또는 "quantity"입니다(예: "price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")

다음 작업을 수행하세요.

  1. 다음 fields를 포함하는 Product struct를 Define하세요.
    • Price (float64) - 제품의 가격
    • Quantity (int) - 제품의 재고 수량
  2. 키가 제품 이름(문자열)이고 값이 Product structs를 가리키는 포인터인 map을 Create하세요.
  3. 두 번째 input에서 제품 데이터를 Parse하세요.
    • input을 commas로 Split하여 individual 제품 entries를 가져옵니다.
    • 각 entry에 대해 colons로 Split하여 이름, 가격, 수량을 분리합니다.
    • 가격 문자열을 float64로, 수량 문자열을 정수로 Convert합니다.
    • Product struct를 Create하고 해당 포인터를 map에 저장합니다.
  4. Parse하는 동안 제품 이름을 별도의 slice에 input에 나타난 order대로 유지하세요. Go에서 map을 순회하면 키가 random order로 방문되므로, 모든 listing을 input order로 유지하는 것은 이 slice입니다.
  5. "Initial Inventory:" header와 함께 initial inventory를 Display하세요.
  6. 각 제품을 다음 Format으로 표시하세요: "[name]: $[price] (Stock: [quantity])"
  7. 세 번째 input의 update operations를 Parse하고 apply하세요.
    • input을 commas로 Split하여 individual operations를 가져옵니다.
    • 각 operation에 대해 colons로 Split하여 operation type, product name, new value를 가져옵니다.
    • map pointer를 통해 appropriate field를 directly 업데이트합니다.
    • 각 update를 다음 Format으로 출력합니다: "Updated [product]: [field] changed to [new_value]"
  8. "Updated Inventory:" header와 함께 updated inventory를 Display하세요.
  9. 각 제품을 initial display와 동일한 Format으로 다시 표시하세요.
  10. 다음과 같이 total inventory value를 Calculate하고 Display하세요: "Total Inventory Value: $[total_value]"

strconv package를 사용하여 가격 및 수량 문자열을 각각의 numeric type으로 Convert하세요. 표시할 때 모든 가격을 소수점 이하 2자리로 Format하세요. 이 과제에서는 map에 포인터를 저장하면 original struct data를 directly 수정할 수 있으므로, map에 값을 다시 할당할 필요 없이 inventory update가 즉시 적용되고 유지된다는 점을 보여 줍니다.

직접 해보기

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: 제품 포인터를 저장할 map 생성
	
	// TODO: 제품 순서를 유지할 slice 생성 (일관된 출력을 보장하기 위해)
	
	// TODO: 제품 데이터를 파싱하고 map을 채우기
	// 다음을 기억하세요:
	// - productDataStr을 쉼표로 분할하여 개별 항목 가져오기
	// - 각 항목에 대해 콜론으로 분할하여 name, price, quantity 가져오기
	// - price와 quantity 문자열을 적절한 타입으로 변환
	// - Product 구조체에 대한 포인터를 map에 저장
	// - 제품 이름을 order slice에 추가
	
	// TODO: Display initial inventory
	// 일관된 출력을 위해 order slice를 사용하여 제품을 순회
	// 형식: "[name]: $[price] (Stock: [quantity])"
	
	// TODO: 업데이트 작업을 파싱하고 적용
	// 다음을 기억하세요:
	// - 개별 작업을 얻기 위해 operationsStr을 쉼표로 분할
	// - 각 작업에 대해 콜론으로 분할하여 type, name, value 얻기
	// - map 포인터를 통해 적절한 필드를 직접 업데이트
	// - 각 작업에 대한 업데이트 메시지 출력
	
	// TODO: Display updated inventory
	// 다시, 일관된 출력을 위해 order 슬라이스 사용
	// 표시하면서 총 가치 계산
	
	// TODO: Calculate and display total inventory value
	// Format: "Total Inventory Value: $[total_value]"
}
quiz icon실력 점검

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

로직 & 흐름의 모든 레슨

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