我想声明一个工厂来帮助我创建用于测试的单例类的实例,而无需在测试运行之间清除类级状态的开销。我的想法是使用工厂返回在函数内声明的类。
我的假设是该类将在运行中创建,并且仅在返回的引用被维护时才会保留。例如:
protocol TestClassFactory {
static func make() -> TestClass.Type
}
protocol TestClass {
static var testValue: String { get set }
}
class Factory: TestClassFactory {
static func make() -> TestClass.Type {
class Tester: TestClass {
static var testValue = "Unmodified"
}
return Tester.self
}
}
Run Code Online (Sandbox Code Playgroud)
然而,在实践中,这并没有按预期工作。具体来说,在第一个make()返回值上设置的静态值会保留到第二个返回值中。
var testClass1 = Factory.make()
print(testClass1.testValue) // "Unmodified"
testClass1.testValue = "Modified"
print(testClass1.testValue) // "Modified"
var testClass2 = Factory.make()
print(testClass2.testValue) // "Modified"
Run Code Online (Sandbox Code Playgroud)
Swift 运行时似乎保留了类,就像在编译时声明和引用的类一样。
我的问题:
Swift 能够在运行时创建新类型,但我认为当前不可能作为语言用户使用该功能。
在 Swift 中,并非所有语句都是可执行的:有些代码仅在编译时评估,并且不会产生可执行代码。类语句就是其中之一。类作用域不会在运行时评估以创建新类:编译器会看到类语句,构建该类,并为您提供对该类的静态引用。这样,当您创建类时,在程序启动时(或任何其他时间)不会执行任何代码。这与其他语言形成鲜明对比,例如 Python,其中每个语句本质上都是可执行的,并且执行类语句实际上会创建一个类。
当您尝试在函数局部类中使用局部变量时,错误会强调此行为:
func foo(int: Int) {
class Bar {
let f = int
// error: class declaration cannot close over value 'int' defined in outer
// scope
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
312 次 |
| 最近记录: |