나만의 데이터 묶음과 바구니: 구조체, 슬라이스, 맵
관련된 데이터를 하나로 묶는 구조체와 가변 배열인 슬라이스, 키-값 저장소인 맵을 다루는 방법을 학습합니다.
우리는 지금까지 숫자(`int`)나 텍스트(`string`) 같은 기본적인 데이터 그릇을 배웠습니다. 하지만 현실의 '유저' 한 명은 회원번호(숫자), 이름(텍스트), 관리자 여부(참/거짓) 등 여러 그릇을 동시에 가져야 합니다. 게다가 게시판에는 유저가 100명이 될지 1만 명이 될지 모르는 상황에서 수많은 유저 데이터를 한꺼번에 담을 거대한 바구니도 필요합니다. 이번 시간에는 연관된 데이터를 묶어주는 나만의 블록인 '구조체'와, 데이터를 쓸어 담는 마법의 바구니인 '슬라이스', '맵'에 대해 알아봅니다.
나만의 레고 블록 설계도: 구조체 (Struct)
기본적인 데이터 타입만으로는 복잡한 커뮤니티 데이터를 표현할 수 없습니다. 이때 프로그래머가 직접 "이름은 문자, 나이는 숫자, 관리자 여부는 참/거짓으로 묶은 새로운 데이터를 '유저'라고 부를게!"라고 나만의 레고 블록 설계도를 선언할 수 있습니다. 이것이 바로 구조체(Struct)입니다.
정의
구조체 (Struct)
서로 다른 타입의 변수들을 논리적으로 끈끈하게 묶어서 하나의 새로운 덩어리로 만든 데이터 타입입니다. 데이터베이스의 테이블 한 줄(가로줄)을 그대로 코드로 옮겨온 것과 완전히 똑같은 역할을 합니다.
유저 구조체 만들기
// 1. 설계도 만들기
type User struct {
ID int
Name string
IsAdmin bool
}
// 2. 설계도를 보고 실제 데이터 덩어리(객체) 찍어내기
newUser := User{
ID: 1,
Name: "홍길동",
IsAdmin: false,
}바이브코딩에서 데이터베이스 테이블을 새로 추가할 때, AI는 항상 위와 같이 백엔드 코드 어딘가에 해당 테이블과 똑같이 생긴 구조체(Struct)를 세트로 만들어냅니다.
늘어나는 고무줄 바구니: 슬라이스 (Slice)
유저 한 명을 구조체로 만들었으니, 이제 게시판의 '유저 목록'을 담아보겠습니다. 유저가 총 몇 명 가입할지 처음부터 알 수 없으므로, 데이터가 추가될 때마다 알아서 쭈욱쭈욱 늘어나는 고무줄 같은 바구니가 필요합니다. Go 언어에서는 이 가변형 리스트를 슬라이스(Slice)라고 부릅니다.
슬라이스에 데이터 담기
go```go
// User 구조체들을 넉넉히 담을 수 있는 빈 바구니(슬라이스) 준비
var userList []User
// append를 사용해 홍길동과 이순신을 차례대로 바구니에 담기
userList = append(userList, User{ID: 1, Name: "홍길동"})
userList = append(userList, User{ID: 2, Name: "이순신"})
```- 11. 대괄호 [] 안에 타입을 적으면 '그 타입을 담을 수 있는 늘어나는 바구니'가 탄생합니다.
- 22. append() 라는 내장 마법 주문을 사용해 바구니의 맨 끝에 새로운 데이터를 쑥쑥 밀어 넣습니다.
- 33. 바구니가 가득 차면 Go 언어가 알아서 두 배 큰 바구니로 갈아 끼우고 데이터를 옮겨 담아줍니다.
이름표가 붙은 사물함: 맵 (Map)
슬라이스는 들어온 순서대로 데이터를 차곡차곡 쌓기 때문에, 나중에 1만 개의 데이터 중에서 "이순신"을 찾으려면 1번부터 1만 번까지 다 뒤져야 하는 단점이 있습니다.
검색이 자주 필요할 때는 1번부터 순서대로 쌓는 대신, 아예 사물함에 '이름표'를 붙여놓고 보관하는 방법이 최고입니다. 열쇠(이름표)만 있으면 데이터가 100만 개든 1000만 개든 단 0.001초 만에 서랍을 덜컥 열고 데이터를 꺼낼 수 있습니다. 이 마법의 사물함을 맵(Map)이라고 부릅니다.
빠른 검색을 위한 맵(Map) 사용
// map[열쇠타입]알맹이타입
// "문자열 열쇠를 주면 정수 알맹이를 돌려주는 사물함"을 만듭니다.
pointBox := make(map[string]int)
// 서랍 앞에 이름표를 붙여서 포인트 값을 넣습니다.
pointBox["홍길동"] = 5000
pointBox["이순신"] = 3000
// 100만 개의 데이터가 있어도, 이순신 서랍을 즉시 열어 3000을 꺼냅니다.
fmt.Println(pointBox["이순신"])컬렉션 선택 실무 팁
- 1게시판 글 목록, 최근 댓글 등 '순서'가 중요하고 정렬이 필요한 데이터는 무조건 슬라이스(Slice) 바구니를 사용합니다.
- 2세션 정보, 캐시 데이터 등 순서는 하나도 안 중요하지만 '특정 ID로 엄청나게 빠르게 검색'해야 하는 데이터는 무조건 맵(Map) 사물함을 씁니다.
개념 퀴즈
퀴즈 답을 맞춰야 학습 완료가 됩니다.우리 서비스에서 유저가 로그인할 때, 유저의 고유 ID(문자열)를 열쇠로 삼아 해당 유저의 로그인 성공 횟수(정수형 숫자)를 0.001초 만에 엄청나게 빠르게 찾아오고 싶습니다. 순서는 전혀 중요하지 않습니다. 이를 구현하기 위해 사용할 Go 언어의 데이터 구조로 가장 알맞은 것은 무엇인가요?
3줄 요약
- 1구조체(Struct)는 서로 다른 타입의 데이터들을 끈끈하게 묶어 데이터베이스의 테이블 한 줄과 똑같은 형태의 덩어리를 만들어 냅니다.
- 2슬라이스(Slice)는 데이터가 들어올 때마다 길이가 무한정 늘어나는 고무줄 리스트로, 순서가 중요한 목록을 담을 때 씁니다.
- 3맵(Map)은 열쇠와 알맹이를 짝지어 저장하는 구조로, 데이터의 순서보다 압도적으로 빠른 검색 속도가 필요할 때 사용합니다.