-
[SE-0502] Exclude private initialized properties from memberwise initializerSwift 2026. 1. 11. 09:51
안녕하세요. 그린입니다 🍏
이번 포스팅에서는 SE-0502 Exclude private initialized properties from memberwise initializer에 대해 정리해보겠습니다 🙋🏻

Intro
Swift에서 struct를 사용하다 보면, 의식하지 않아도 자연스럽게 활용하게 되는 기능 중 하나가 바로 memberwise initializer입니다.
저장 프로퍼티를 선언하기만 하면, 컴파일러가 알아서 이니셜라이저를 만들어 주는 기능이죠.
하지만 이 편리한 기능은, 접근 제어자(private, fileprivate)와 엮이기 시작하면 생각보다 많은 불편함과 함정을 드러냅니다.
이번 글에서는 Swift Evolution Proposal SE-0502 – Exclude private initialized properties from memberwise initializer의 내용을 그대로 따라가며, 왜 이런 제안이 나왔고, 무엇을 바꾸려 하는지, 그리고 이 변화가 실제 개발에서 어떤 의미를 가지는지를 한번 알아보겠습니다 🚀
swift-evolution/proposals/0502-exclude-private-from-memberwise-init.md at main · swiftlang/swift-evolution
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution
github.com
memberwise initializer의 기본 동작
Swift에서 struct를 선언하면, 컴파일러는 저장 프로퍼티들을 기반으로 자동으로 memberwise initializer를 생성합니다.
struct Point { let x: Int let y: Int }위 코드는 아래와 같은 이니셜라이저가 자동으로 생성됩니다.
init(x: Int, y: Int)여기까지는 모두가 익숙한 동작입니다. 문제는 접근 수준(access level) 이 개입되기 시작할 때 발생합니다.
접근 수준이 memberwise initializer에 미치는 영향
Swift의 규칙은 단순합니다.
memberwise initializer의 접근 수준은, 모든 저장 프로퍼티의 접근 수준 중 가장 제한적인 수준을 따른다.
즉, 저장 프로퍼티 중 하나라도 private이면, memberwise initializer 전체가 private이 됩니다.
struct Example { var a: Int var b: Int private var c: Int = 0 }이 경우 컴파일러가 생성하는 이니셜라이저는 다음과 같습니다.
private init(a: Int, b: Int, c: Int)여기서 핵심은 c가 이미 초기값을 가지고 있음에도 불구하고, 이니셜라이저의 파라미터로 포함된다는 점입니다.
그리고 그 결과, 전체 이니셜라이저가 private이 되어 버립니다.
즉, 외부에서는 Example(a:b:)조차 사용할 수 없게 됩니다.
실제로 이게 왜 문제일까?
이 동작은 문법적으로는 일관성이 있지만, 실무에서는 상당히 불편합니다.
- 외부에서 설정할 필요가 없는 내부 상태를 private으로 감췄을 뿐인데
- 그로 인해 타입 전체를 생성할 수 없게 되는 상황이 발생합니다
그래서 개발자들은 보통 아래와 같은 선택을 강요받습니다.
- 불필요하게 internal이나 public으로 접근 수준을 올리거나
- 명시적으로 이니셜라이저를 직접 작성하거나
memberwise initializer의 장점을 스스로 포기하게 되는 것이죠.
SE-0502 제안의 요점
SE-0502는 바로 이 지점에서 출발합니다.
초기값을 이미 가지고 있고, 외부에서 설정할 필요가 없는 private 프로퍼티 때문에
memberwise initializer 전체가 제한되는 것이 과연 합리적인가?이 제안은 기존 규칙을 완전히 뒤엎으려는 것이 아닙니다.
대신, "이미 초기값이 있는 private 프로퍼티" 라는 굉장히 구체적인 조건에만 변화를 주려 합니다.
제안되는 새로운 규칙
SE-0502가 제안하는 동작은 다음과 같습니다.
- 먼저, memberwise initializer가 가질 수 있는 최대 접근 수준을 계산한다
- 그 접근 수준보다 더 제한적인 접근 수준을 가진 저장 프로퍼티 중에서
- 초기값이 이미 있는 프로퍼티는 memberwise initializer에서 제외한다
즉, 이런 프로퍼티들은 아예 이니셜라이저의 파라미터 목록에 포함되지 않습니다.
변경 후 동작 예시
다시 앞의 예제를 보겠습니다.
struct Example { var a: Int var b: Int private var c: Int = 0 }SE-0502가 적용되면, 컴파일러는 다음과 같은 이니셜라이저를 생성합니다.
init(a: Int, b: Int)- c는 이미 기본값을 가지고 있고
- 접근 수준이 더 제한적이며
- 외부에서 설정할 필요가 없기 때문에
memberwise initializer에서 완전히 제외됩니다.
그 결과, 타입을 사용하는 쪽에서는 아무 불편 없이 Example(a:b:)를 사용할 수 있고, 내부 구현 세부 사항은 깔끔하게 감춰집니다.
property wrapper, macro와의 일관성
이 제안은 단순히 불편함을 줄이기 위한 것만은 아닙니다.
이미 Swift에는 비슷한 사례가 존재합니다.
Property wrapper는 내부적으로 backing storage를 생성합니다.
이 backing storage는 대부분 private이며, memberwise initializer에 노출되지 않습니다.
매크로 역시 내부 구현을 위해 private 저장 프로퍼티를 생성할 수 있습니다.
이 경우에도, 그 프로퍼티가 memberwise initializer에 노출된다면 매크로 사용성이 크게 떨어집니다.
SE-0502는 이런 기존 언어 기능들과 memberwise initializer의 동작을 일관되게 맞추려는 목적도 가지고 있습니다.
ABI와 소스 호환성
- 이 변경은 ABI에 영향을 주지 않습니다
- memberwise initializer는 컴파일러가 합성하는 구현 세부사항이기 때문입니다
- 다만 소스 호환성 측면에서는 일부 영향이 있을 수 있습니다
- 기존에 private memberwise initializer를 의도적으로 사용하던 코드라면
- 명시적인 이니셜라이저 선언이 필요해질 수 있습니다
하지만 제안서에서는, 이런 경우가 매우 제한적일 것이라고 판단하고 있습니다.
이 제안의 의미
SE-0502는 아주 작은 규칙 변경처럼 보이지만, Swift가 지향하는 방향을 잘 보여줍니다.
- 내부 구현 디테일은 내부에 감추고
- 외부 API는 최대한 단순하고 명확하게 유지하며
- 컴파일러가 개발자의 의도를 더 잘 추론하도록 돕는 방향
memberwise initializer를 다시 "편하게 써도 되는 기능"으로 돌려놓기 위한, 꽤 합리적인 개선이라고 볼 수 있습니다.
Conclusion
현재 시점에서 swift lang에 머지는 된것 같아 곧 다음 버전에서 같이 릴리즈 되지 않을까 기대합니다.
그래도 아직 논의와 리뷰가 계속 이어지고 있긴 한것 같은데 어떤 방향으로 결론이 날지 궁금하네요 😃
References
swift-evolution/proposals/0502-exclude-private-from-memberwise-init.md at main · swiftlang/swift-evolution
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution
github.com
Swift.org
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
www.swift.org
'Swift' 카테고리의 다른 글
[SE-0504] Task Cancellation Shields (1) 2026.01.17 Embedded Swift Improvements Coming in Swift 6.3 (0) 2025.12.26 Nonexhaustive enums - Swift 6.2.3 (2) 2025.12.20 NSAttributedString Performance Optimization (0) 2025.12.06 Swift Closure Capture Semantics (0) 2025.11.15