文档只提到了嵌套类型,但不清楚它们是否可以用作命名空间。我没有找到任何显式提到命名空间的内容。
文档只提到了嵌套类型,但不清楚它们是否可以用作命名空间。我没有找到任何显式提到命名空间的内容。
我认为Swift的命名空间是有抱负性的,它已经被赋予了很多广告宣传,但这与实际上并没有任何有意义的联系。
例如,WWDC视频中指出,如果你导入的框架有一个类MyClass,而你的代码也有一个类MyClass,那么这些名称不会冲突,因为“名称修饰”会给它们不同的内部名称。然而在现实中,它们确实会发生冲突,因为你自己的代码的MyClass会覆盖,你无法指定“不不,我是指框架中的MyClass”——说TheFramework.MyClass没用(编译器知道你的意思,但它会说找不到框架中的这个类)。
我的经验是,Swift实际上根本没有命名空间。在将我的应用程序从Objective-C转换为Swift时,我创建了一个嵌入式框架,因为这样做非常容易和酷。然而,导入该框架会导入框架中的所有Swift内容 - 因此,再次出现了一个全局的命名空间。而且没有Swift头文件,所以你不能隐藏任何名称。
编辑:在3号种子版本中,这个功能现在开始上线,具体来说:如果你的主代码包含MyClass,而你的框架MyFramework包含MyClass,则默认情况下前者会覆盖后者,但是你可以使用语法MyFramework.MyClass
来访问后者。因此,我们实际上有了一个独立的命名空间的雏形!
编辑2:在种子版本4中,我们现在拥有访问控制!此外,在我的一款应用程序中,我有一个嵌入式框架,确实,所有内容都默认隐藏,我必须显式地公开所有的公共API部分。这是一个很大的改进。
Foundation.NSArray
来引用它。 - mattSevenTenEleven在Apple开发论坛中回答:
命名空间不是按文件而是按目标进行的(基于“产品模块名称”构建设置)。因此,你最终会得到类似这样的结果:
import FrameworkA import FrameworkB FrameworkA.foo()
所有的Swift声明都被认为是某个模块的一部分,所以即使你说 "
NSLog
"(是的,它仍然存在),你得到的也是Swift认为的 "Foundation.NSLog
"。Chris Lattner 在推特上发表了关于命名空间的言论。
在Swift中,命名空间是隐式的,所有的类(等等)都隐含地由它们所在的模块(Xcode目标)作用域限定,不需要类前缀。
这似乎和我之前想的很不一样。
forums.developer.apple.com
论坛网站中。 - Dai在进行一些实验时,我通过扩展根“包”来创建了这些自己文件中的“命名空间”类。不确定是否违反最佳实践或是否有任何我不知道的影响(?)
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中),通过在一个文件中定义包,可以在单独的文件中扩展它们。
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..."
为什么?因为你声明的内容是在当前模块中声明的,也就是你的当前目标。而UIKit
中的UICollectionViewController
是在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
extension
来使用所提到的struct
方法进行命名空间,而无需将所有代码缩进到右侧。我已经尝试了一下,不确定是否要像下面的示例中创建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
}
}
如果有人感兴趣,在2014年6月10日,Swift存在一个已知的bug:
来自SevenTenEleven
"已知的bug,抱歉!rdar://problem/17127940 通过模块名称限定Swift类型无法正常工作。"