ドキュメントにはネストされた型のみが記載されていますが、名前空間として使用できるかどうかは明確ではありません。名前空間の明示的な言及は見つかりませんでした。
Apple開発フォーラム のSevenTenElevenが回答
名前空間はファイルごとではありません。それらはターゲットごとです(「製品モジュール名」ビルド設定に基づきます)。したがって、次のような結果になります。
import FrameworkA import FrameworkB FrameworkA.foo()
すべてのSwift宣言は一部のモジュールの一部とみなされるため、「
NSLog
」と言っても(はい、まだ存在します)、Swiftが「Foundation.NSLog
」と考えるものが得られます。 「。
Chris Lattnerネームスペースについてツイート .
Swiftでは名前空間は暗黙的であり、すべてのクラス(など)は、それらが含まれるモジュール(Xcodeターゲット)によって暗黙的にスコープされます。
私が考えていたものとは非常に異なるようです。
私は、Swiftのネームスペースを野心的なものとして説明します。地上の意味のある現実に対応していない広告が多く提供されています。
たとえば、WWDCビデオでは、インポートするフレームワークにクラスMyClassがあり、コードにクラスMyClassがある場合、「名前マングリング」が異なる内部名を与えるため、これらの名前は競合しません。ただし、実際には、doは競合します。つまり、独自のコードのMyClassが勝つという意味で、「いいえ、いいえ、私はフレームワークのMyClass」— TheFramework.MyClass
が機能しないと言っています(コンパイラはあなたの意味を知っていますが、フレームワークでそのようなクラスを見つけることができないと言います)。
私の経験では、Swiftは少しでも名前空間化されていません。私のアプリの1つをObjective-CからSwiftに変えたときに、組み込みフレームワークを作成しました。ただし、フレームワークをインポートすると、フレームワーク内のすべてのSwiftものがインポートされます。したがって、今でも、名前空間は1つだけでグローバルです。また、Swiftヘッダーがないため、名前を隠すことはできません。
EDIT:シード3では、この機能は次の意味でオンラインになり始めています:メインコードにMyClassが含まれ、フレームワークMyFrameworkにMyClassが含まれる場合、前者はデフォルトで後者を覆い隠しますが、構文MyFramework.MyClass
を使用して、フレームワーク内の1つに到達できます。したがって、実際には別個の名前空間の基礎があります!
編集2:シード4では、アクセス制御ができました!さらに、私のアプリの1つには、組み込みのフレームワークがあり、確かに、デフォルトではすべてが隠されていたため、パブリックAPIのすべてのビットを明示的に公開する必要がありました。これは大きな改善です。
これでいくつかの実験を行っている間、ルート「パッケージ」を拡張することにより、独自のファイルにこれらの「名前空間」クラスを作成することになりました。これがベストプラクティスに反するのか、それとも私が気づいている意味を持っているのかどうかはわかりません(?)
AppDelegate.Swift
var n1 = PackageOne.Class(name: "Package 1 class")
var n2 = PackageTwo.Class(name: "Package 2 class")
println("Name 1: \(n1.name)")
println("Name 2: \(n2.name)")
PackageOne.Swift
import Foundation
struct PackageOne {
}
PackageTwo.Swift
import Foundation
struct PackageTwo {
}
PackageOneClass.Swift
extension PackageOne {
class Class {
var name: String
init(name:String) {
self.name = name
}
}
}
PackageTwoClass.Swift
extension PackageTwo {
class Class {
var name: String
init(name:String) {
self.name = name
}
}
}
編集:
上記のコードで「サブパッケージ」を作成すると、別のファイルを使用すると機能しなくなることがわかりました。たぶん、誰かがそれがどうしてそうなるのかを示唆できるでしょうか?
上記に次のファイルを追加します。
PackageOneSubPackage.Swift
import Foundation
extension PackageOne {
struct SubPackage {
}
}
PackageOneSubPackageClass.Swift
extension PackageOne.SubPackage {
class Class {
var name: String
init(name:String) {
self.name = name
}
}
}
コンパイラエラーのスロー: 'SubPackage'は 'PackageOne'のメンバータイプではありません
PackageOneSubPackageClass.SwiftからPackageOneSubPackage.Swiftにコードを移動すると機能します。誰でも?
編集2:
これをいじくりまわし、(Xcode 6.1 beta 2で)パッケージを1つのファイルで定義することで、それらを別のファイルに拡張できることを発見しました。
public struct Package {
public struct SubPackage {
public struct SubPackageOne {
}
public struct SubPackageTwo {
}
}
}
Gistのファイルは次のとおりです。 https://Gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
私はこれを使用して達成されると信じています:
struct Foo
{
class Bar
{
}
}
次に、以下を使用してアクセスできます。
var dds = Foo.Bar();
名前空間は、既存のフレームワークのクラスと同じ名前でクラスを定義する必要がある場合に役立ちます。
アプリに
MyApp
名があり、カスタムUICollectionViewController
を宣言する必要があるとします。
必要ないこのようにプレフィックスとサブクラスを作成するには:
class MAUICollectionViewController: UICollectionViewController {}
次のようにします:
class UICollectionViewController {} //no error "invalid redeclaration o..."
なぜ?。宣言したものはcurrent moduleで宣言されているため、これはcurrent targetです。そして、UICollectionViewController
からのUIKit
がUIKit
モジュールで宣言されています。
現在のモジュール内での使用方法
var customController = UICollectionViewController() //your custom class
var uikitController = UIKit.UICollectionViewController() //class from UIKit
他のモジュールと区別する方法
var customController = MyApp.UICollectionViewController() //your custom class
var uikitController = UIKit.UICollectionViewController() //class from UIKit
2014年6月10日の時点で誰もが好奇心が強い場合、これはSwiftの既知のバグです。
SevenTenElevenから
「既知のバグ、ごめんなさい!rdar:// problem/1712794モジュール名でSwiftタイプを修飾しても機能しません。」
extension
を使用すると、前述のstruct
sアプローチを使用して、すべてのコードを右にインデントすることなく、ネームスペースを作成できます。私はこれを少しいじっていましたが、以下の例のようにControllers
とViews
名前空間を作成するかどうかはわかりませんが、それがどこまで行くことができるかを示しています:
Profiles.Swift:
// Define the namespaces
struct Profiles {
struct Views {}
struct ViewControllers {}
}
Profiles/ViewControllers/Edit.Swift
// Define your new class within its namespace
extension Profiles.ViewControllers {
class Edit: UIViewController {}
}
// Extend your new class to avoid the extra whitespace on the left
extension Profiles.ViewControllers.Edit {
override func viewDidLoad() {
// Do some stuff
}
}
Profiles/Views/Edit.Swift
extension Profiles.Views {
class Edit: UIView {}
}
extension Profiles.Views.Edit {
override func drawRect(rect: CGRect) {
// Do some stuff
}
}
このレベルの分離はまだ必要ないので、アプリでこれを使用していませんが、面白いアイデアだと思います。これにより、ユビキタスな* ViewControllerサフィックスのようなクラスサフィックスさえも不要になります。
ただし、次のようなメソッドパラメーターなどで参照されている場合は短縮されません。
class MyClass {
func doSomethingWith(viewController: Profiles.ViewControllers.Edit) {
// secret sauce
}
}