Swift로 개발하다 보면 꼭 한 번은 멈칫하는 순간이 옵니다.
“이거 class로 만들까, struct로 만들까?”
저도 처음 Swift를 배울 때 이 둘을 그냥 기분 따라 골랐어요. 그러다 이상한 버그를 겪고 나서야 차이를 제대로 공부하게 됐습니다.
결론부터 말씀드릴게요.
특별한 이유가 없다면 구조체(struct)를 먼저 선택하세요.
클래스는 “공유되는 하나의 상태”가 꼭 필요할 때만 씁니다.
애플 공식 가이드라인도 같은 입장입니다. 오늘은 그 이유를 하나씩 풀어드릴게요.
핵심 요약부터 (3가지)
바쁜 분들을 위해 먼저 정리했어요.
- 구조체는 값 타입입니다. 복사하면 완전히 다른 값이 됩니다.
- 클래스는 참조 타입입니다. 복사해도 같은 인스턴스를 함께 가리킵니다.
- 헷갈리면 일단 struct, 상속이나 공유 상태가 필요할 때만 class.
이 세 줄만 기억해도 절반은 끝났습니다.
값 타입과 참조 타입, 뭐가 다른가요?
말로만 들으면 아리송하죠. 코드로 보는 게 제일 빠릅니다.
먼저 구조체입니다. 복사한 순간 서로 남남이 됩니다.
struct Point { var x = 0 }
var a = Point()
var b = a // 값이 복사됨
b.x = 10
print(a.x, b.x)
// 출력: 0 10
b를 바꿔도 a는 그대로예요. 각자 자기 값을 가지고 있으니까요.
이번엔 클래스입니다. 같은 코드처럼 보이지만 결과가 다릅니다.
class Box { var x = 0 }
let a = Box()
let b = a // 참조가 복사됨 (같은 객체)
b.x = 10
print(a.x, b.x)
// 출력: 10 10
b만 바꿨는데 a까지 10이 됐죠.
둘이 같은 인스턴스를 가리키니까요. 저를 괴롭혔던 그 버그가 바로 이거였어요.
그래서 언제 뭘 쓰나요? (선택 기준)
실무에서 판단할 때 저는 이 표를 머릿속에 떠올립니다.
| 상황 | 판단 |
|---|---|
| 단순히 데이터를 담는 모델 | 구조체 |
| 복사돼도 서로 독립적이길 원함 | 구조체 |
| 상속이 꼭 필요함 | 클래스 |
| 여러 곳에서 같은 인스턴스를 공유 | 클래스 |
| Objective-C와 연동해야 함 | 클래스 |
조금 더 풀어서 정리하면 이렇습니다.
- 좌표, 색상, 크기처럼 값 그 자체를 표현하면 구조체가 자연스럽습니다.
- 화면 컨트롤러나 네트워크 매니저처럼 하나의 상태를 여러 곳이 함께 봐야 하면 클래스가 맞습니다.
- 애플의 SwiftUI가 View를 struct로 만든 것도 같은 이유예요. 가볍고 예측 가능하니까요.
참고로 Swift 표준 라이브러리의 Array, String, Dictionary가 전부 구조체입니다. 그만큼 값 타입이 기본이라는 뜻이죠.
구조체를 먼저 권하는 이유
값 타입은 예측이 쉽습니다.
내가 넘긴 값이 다른 곳에서 몰래 바뀔 걱정이 없어요. 함수에 넘겨도 원본은 안전합니다.
멀티스레드 환경에서도 마음이 편합니다. 공유되는 상태가 없으니 데이터 경합이 줄어들거든요.
반대로 클래스는 강력하지만 조심스럽습니다. 여기저기서 같은 인스턴스를 붙잡고 있으면, 값이 어디서 바뀌는지 추적하기가 어려워요.
그래서 “기본은 struct, 필요할 때만 class”라는 습관이 버그를 크게 줄여줍니다.
언제 쓰고 언제 피해야 할까
마지막으로 판단 기준을 짧게 압축했습니다.
- 구조체를 쓰세요: 데이터 중심 모델, 독립적인 복사가 필요할 때, 스레드 안전이 중요할 때
- 클래스를 쓰세요: 상속이 필요할 때, 하나의 인스턴스를 공유해야 할 때, 식별자(identity)가 의미 있을 때
- 피하세요: 단순 모델인데 습관적으로 class를 쓰는 것, 공유가 필요한데 struct로 억지로 우회하는 것
면접에서는 이렇게 물어봅니다
Q. 구조체와 클래스의 가장 큰 차이는 무엇인가요?
구조체는 값 타입, 클래스는 참조 타입입니다. 구조체는 복사하면 완전히 독립된 값이 되지만 클래스는 복사해도 같은 인스턴스를 가리킵니다. 또 클래스만 상속이 가능하고 소멸자(deinit)를 둘 수 있습니다.
Q. Swift는 왜 구조체 사용을 권장하나요?
값 타입은 공유 상태가 없어 부작용이 적고 예측 가능하기 때문입니다. 원본이 의도치 않게 바뀔 위험이 없고 멀티스레드 환경에서도 안전해 버그를 줄이는 데 유리합니다.
처음엔 저도 이 둘이 그저 문법 차이인 줄 알았는데, 파고들수록 설계의 문제더라고요.
오늘 기준만 손에 익혀두시면 다음 프로젝트부터는 덜 망설이실 거예요. 값이냐 공유냐, 딱 이 질문부터 던져보세요!
