该文档仅提及嵌套类型,但尚不清楚它们是否可用作命名空间。我还没有发现任何有关命名空间的明确提及。
该文档仅提及嵌套类型,但尚不清楚它们是否可用作命名空间。我还没有发现任何有关命名空间的明确提及。
Answers:
在苹果开发论坛中,SevenTenEleven回答了:
命名空间不是按文件的;它们是基于目标的(基于“产品模块名称”构建设置)。因此,您最终将得到如下结果:
import FrameworkA import FrameworkB FrameworkA.foo()
所有Swift声明都被认为是某个模块的一部分,因此即使您说“
NSLog
”(是的,它仍然存在),您也会得到Swift认为的“Foundation.NSLog
”。
克里斯·拉特纳(Chris Lattner)也在推特上发布了有关命名空间的信息。
名称间隔在Swift中是隐式的,所有类(等)都由它们所在的模块(Xcode目标)隐式地作用域。不需要类前缀
似乎与我一直在想的完全不同。
forums.developer.apple.com
,不幸的是,Apple尚未将该线程导入新的论坛站点。
我将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
。
在进行一些实验时,我最终通过扩展根“包”在自己的文件中创建了这些“命名空间”类。不知道这是否违反最佳做法或是否对我有影响(?)
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 {
}
}
}
这是我的要点文件:https : //gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
我相信可以使用以下方法实现:
struct Foo
{
class Bar
{
}
}
然后可以使用以下命令访问它:
var dds = Foo.Bar();
enum
而不是a struct
,因此无法实例化一个Foo
。
Swift使用模块的方式非常类似于python(请参阅此处和此处),正如@Kevin Sylvestre所建议的,您还可以将嵌套类型用作名称空间。
为了扩展@Daniel A. White的答案,在WWDC中,他们正在迅速讨论这些模块。
另外在这里说明:
推断的类型使代码更整洁且不易出错,而模块则消除了标头并提供了名称空间。
当您需要定义与现有框架中的类同名的类时,命名空间很有用。
假设您的应用程序具有
MyApp
名称,并且您需要声明您的customUICollectionViewController
。
您不需要像这样的前缀和子类:
class MAUICollectionViewController: UICollectionViewController {}
像这样做:
class UICollectionViewController {} //no error "invalid redeclaration o..."
为什么?。因为您声明的内容是在当前模块中声明的,这是您当前的目标。并且UICollectionViewController
from 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
您可以使用上面extension
提到的struct
s方法进行命名间隔,而不必向右缩进所有代码。我一直在玩这个,我不确定我是否会像下面的示例中那样去创建Controllers
和Views
命名空间,但是它确实说明了它可以走多远:
Profiles.swift:
// Define the namespaces
struct Profiles {
struct Views {}
struct ViewControllers {}
}
配置文件/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
}
}
配置文件/视图/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中的一个已知错误:
从SevenTenEleven
“已知的错误,抱歉!rdar:// problem / 17127940通过其模块名称限定 Swift类型无效。”