apple/Docs, iOS, Swift
[Swift] New access modifier: package
lgvv
2024. 4. 5. 02:14
New access modifier: package
Introduction
- 현재 다른 모듈에서 특정 심볼에 접근하기 위해서는 public으로 정의되어야 함.
- public 패키지 내외부 모두에서 접근 가능하기에 바람직하지 않음.
- 따라서 새로운 접근제어자를 만들어 심볼의 범위를 더 명확하게 하고자 함.
- Swift 5.9에서 도입
Motivation
- Module Engine in gamePkg:
public struct MainEngine {
public init() { ... }
// `public`으로 의도된 프로퍼티
public var stats: String { ... }
// 동일한 패키지의 `Game`에서만 접근할 수 있는 `run` 함수
public func run() { ... }
}
- Module Game in gamePkg:
import Engine
public func play() {
MainEngine().run() // 동일한 패키지 내에 있으므로 의도한 대로 'run'에 접근할 수있음
}
- Client App in appPkg:
import Game
import Engine
let engine = MainEngine()
engine.run() // 의도한 동작이 아니더라도 앱에서 `run`에 접근할 수 있음.
Game.play()
print(engine.stats) // 의도한대로 `stats`에 접근 가능
Proposed solution
- 동일 패키지에서 사용하기 위한 새로운 접근 제어자 package 도입
Detailed design
package var package: String {...}
- 위의 코드를 아래처럼 개선 가능
public struct MainEngine {
public init() { ... }
public var stats: String { ... }
package func run() { ... }
}
Use Site
import Engine
public func play() {
MainEngine().run() // 동일 모듈이므로 여전히 해당 심볼에 접근할 수 있음
}
하지만 만약 패키지 외부에서 package로 선언된 심볼에 접근하고자 하는 경우에는 접근할 수 없음.
Client App
import Game
import Engine
let engine = MainEngine()
engine.run() // Error: cannot find `run` in scope
Package Names
- 새로운 package 접근 제어자를 해당 타겟에서 사용하지 않으려면 false 작성하면 되며, 해당 모듈에 포함된 package 접근제어자는 사용할 수 없음. 기본은 true
- 아래 코드에 대해서 설명자면 Game 모듈에서 Engine모듈에 포함된 package 접근제어자 사용할 수 없음.
.target(name: "Game", dependencies: ["Engine"], packageAccess: false)
Subclassing and Overrides
- 각 현재 액세스 레벨의 심볼을 사용하거나 override 할 수 있는 위치를 보여주는 표
- package가 추가되고 아래처럼 수정
- 현재 입력할 별도의 규칙이 정해지지 않았으며, 향후 논의를 통해 결정
- 현재 입력할 별도의 규칙이 정해지지 않았으며, 향후 논의를 통해 결정
(참고링크)
https://github.com/lgvv/wiki/issues/18