PHpullh
학습 라이브러리/Go/불변 데이터 설계

GO · 함수형

불변 데이터 설계

값 타입과 복사를 활용하여 불변 데이터 구조를 설계합니다. 동시성 안전성을 보장합니다.

함수형고급immutablevalue-typedefensive-copythread-safe

핵심 설명

값 타입과 복사를 활용하여 불변 데이터 구조를 설계합니다. 동시성 안전성을 보장합니다.

Go code

package main

import "fmt"

// 불변 구조체: 모든 메서드가 새 인스턴스 반환
type Point struct{ X, Y float64 }

func (p Point) Move(dx, dy float64) Point {
	return Point{X: p.X + dx, Y: p.Y + dy}
}

func (p Point) Scale(factor float64) Point {
	return Point{X: p.X * factor, Y: p.Y * factor}
}

// 불변 슬라이스: 항상 복사 후 수정
type ImmutableList[T any] struct {
	items []T
}

func NewList[T any](items ...T) ImmutableList[T] {
	cp := make([]T, len(items))
	copy(cp, items)
	return ImmutableList[T]{items: cp}
}

func (l ImmutableList[T]) Append(v T) ImmutableList[T] {
	newItems := make([]T, len(l.items)+1)
	copy(newItems, l.items)
	newItems[len(l.items)] = v
	return ImmutableList[T]{items: newItems}
}

func (l ImmutableList[T]) Items() []T {
	cp := make([]T, len(l.items))
	copy(cp, l.items)
	return cp
}

func main() {
	p := Point{1, 2}
	p2 := p.Move(3, 4).Scale(2)
	fmt.Println(p)  // {1 2} — 원본 변경 없음
	fmt.Println(p2) // {8 12}

	list := NewList(1, 2, 3)
	list2 := list.Append(4)
	fmt.Println(list.Items())  // [1 2 3]
	fmt.Println(list2.Items()) // [1 2 3 4]
}

학습 팁

값 리시버 + 새 인스턴스 반환 패턴은 불변성을 보장합니다. 메서드 체이닝도 자연스럽게 지원됩니다.

주의할 점

슬라이스를 직접 반환하면 외부에서 수정할 수 있습니다. 항상 copy로 방어적 복사를 수행하세요.

자주 묻는 질문

불변 데이터 설계란 무엇인가요?

값 타입과 복사를 활용하여 불변 데이터 구조를 설계합니다. 동시성 안전성을 보장합니다.

불변 데이터 설계 학습 시 주의할 점은 무엇인가요?

슬라이스를 직접 반환하면 외부에서 수정할 수 있습니다. 항상 copy 로 방어적 복사를 수행하세요.