はじめに
Swiftの@_exported
について、その挙動を調査したのでまとめる。
@_exported
とは
- _がプレフィックスとしてついており、Swiftで公式には公開されていないAttribute
- 以下のようにimport文で利用可能
@_exported import Foo
挙動調査
前提
以下のような3階層のモジュール構成を考える。
├── Main
│ └── Main.swift
├── SubModule
│ ├── SubModule1.swift
│ └── SubModule2.swift
└── SubSubModule
└── SubSubModule.swift
同一モジュール内への影響調査
SubModule1.swiftにて、@_exported import SubSubModule
を記述する。
ファイルをまたいでSubModule2.swiftでもSubSubModule.swiftのAPIが利用できる。
├── Main
│ └── Main.swift
├── SubModule
│ ├── SubModule1.swift // @_exported import SubSubModuleを記述
│ └── SubModule2.swift // SubSubModule.swiftのAPIが利用できる
└── SubSubModule
└── SubSubModule.swift
上位モジュールへの影響調査
さらに、Main.swiftにて、import SubModule
を記述する。
モジュールをまたいでMain.swiftでもSubModule.swiftのAPIが利用できる。
├── Main
│ └── Main.swift // import SubModuleを記述、SubSubModule.swiftのAPIが利用できる
├── SubModule
│ ├── SubModule1.swift // @_exported import SubSubModuleを記述
│ └── SubModule2.swift
└── SubSubModule
└── SubSubModule.swift
おわりに
-
@_exported
をimportに付与すると、同一モジュール内でのimportが不要になる - また、上位モジュールが下位モジュールをimportでインポートした場合、下位モジュールで
@_exported
でimportされている孫関係にあたる下位モジュールもimportされる - 以下のように、UIKitをimportするだけで、FoundationをimportしなくてもFoundationのAPIが利用できることから、UIKit内部で
@_exported import Foundation
が定義されていると推測される
import UIKit
import Foundation // import不要
参考
- https://forums.swift.org/t/exported-and-fixing-import-visibility/9415
- https://stackoverflow.com/questions/41000256/what-is-import-func-struct-class-and-exported-in-swift
- https://stackoverflow.com/questions/33558995/what-is-the-exported-attribute-in-swift
- https://medium.com/eureka-engineering/create-merged-framework-to-cut-appstartuptime-72ee67b2bbab