设置惰性静态变量首先初始化然后分配?
Setting lazy static variable first initializes then assigns?
我意识到static
变量是隐含的lazy
,这真是太棒了。在首次调用之前,执行以下操作不会创建实例:
static var test = Test()
但是,将新实例分配给 static
变量会初始化原始实例,然后分配新实例,这对我来说很麻烦:
SomeType.test = AnotherTest() //Initializes Test then AnotherTest type
为了提供更多关于我正在尝试做的事情的背景信息,我正在尝试使用 this article 设置一个纯粹的 Swift 依赖注入。在我的单元测试中交换类型时效果不佳,因为在分配模拟类型时总是会初始化原始类型。
这是一个更完整的 playground 示例:
protocol MyProtocol { }
class MyClass: MyProtocol {
init() { print("MyClass.init") }
}
////
struct MyMap {
static var prop1: MyProtocol = MyClass()
}
protocol MyInject {
}
extension MyInject {
var prop1: MyProtocol { return MyMap.prop1 }
}
////
class MyMock: MyProtocol {
init() { print("MyMock.init") }
}
// Swapping types underneath first initializes
// original type, then mock type :(
MyMap.prop1 = MyMock()
prints: MyClass.init
prints: MyMock.init
如何让MyMap.prop1 = MyMock()
不先初始化原来的MyClass
?
您需要延迟加载。试试这个:
struct MyMap {
private static var _prop1: MyProtocol?
static var prop1: MyProtocol {
get { return _prop1 ?? MyClass() }
set(value) { _prop1 = value }
}
}
或者这样:
struct MyMap {
private static var _prop1: MyProtocol?
static var prop1: MyProtocol {
get {
if _prop1 == nil {
_prop1 = MyClass()
}
return _prop1!
}
set(value) { _prop1 = value }
}
}
我意识到static
变量是隐含的lazy
,这真是太棒了。在首次调用之前,执行以下操作不会创建实例:
static var test = Test()
但是,将新实例分配给 static
变量会初始化原始实例,然后分配新实例,这对我来说很麻烦:
SomeType.test = AnotherTest() //Initializes Test then AnotherTest type
为了提供更多关于我正在尝试做的事情的背景信息,我正在尝试使用 this article 设置一个纯粹的 Swift 依赖注入。在我的单元测试中交换类型时效果不佳,因为在分配模拟类型时总是会初始化原始类型。
这是一个更完整的 playground 示例:
protocol MyProtocol { }
class MyClass: MyProtocol {
init() { print("MyClass.init") }
}
////
struct MyMap {
static var prop1: MyProtocol = MyClass()
}
protocol MyInject {
}
extension MyInject {
var prop1: MyProtocol { return MyMap.prop1 }
}
////
class MyMock: MyProtocol {
init() { print("MyMock.init") }
}
// Swapping types underneath first initializes
// original type, then mock type :(
MyMap.prop1 = MyMock()
prints: MyClass.init
prints: MyMock.init
如何让MyMap.prop1 = MyMock()
不先初始化原来的MyClass
?
您需要延迟加载。试试这个:
struct MyMap {
private static var _prop1: MyProtocol?
static var prop1: MyProtocol {
get { return _prop1 ?? MyClass() }
set(value) { _prop1 = value }
}
}
或者这样:
struct MyMap {
private static var _prop1: MyProtocol?
static var prop1: MyProtocol {
get {
if _prop1 == nil {
_prop1 = MyClass()
}
return _prop1!
}
set(value) { _prop1 = value }
}
}