Arrays 单个数组元素的惰性初始化
在Swift中,允许我们仅在请求时初始化类成员,而不是在运行时直接初始化,这对于计算代价高昂的操作非常有用 我在Swift 4中有一个类,负责从Arrays 单个数组元素的惰性初始化,arrays,swift,lazy-initialization,Arrays,Swift,Lazy Initialization,在Swift中,允许我们仅在请求时初始化类成员,而不是在运行时直接初始化,这对于计算代价高昂的操作非常有用 我在Swift 4中有一个类,负责从StrategyProtocol对象提供的编译时数组(开发人员硬编码)初始化一个。它看起来像这样: class StrategyFactory { private var availableStrategies: [StrategyProtocol] = [ OneClassThatImplementsStrategyProtoc
StrategyProtocol
对象提供的编译时数组(开发人员硬编码)初始化一个。它看起来像这样:
class StrategyFactory {
private var availableStrategies: [StrategyProtocol] = [
OneClassThatImplementsStrategyProtocol(),
AnotherThatImplementsStrategyProtocol() // etc
]
public func createStrategy(): StrategyProtocol {
// Depending on some runtime-calculated operation
// How do I do this nicely here?
}
}
但是,根据我的理解,在每个策略的末尾放置()
会初始化对象(?),而我可能只想根据特定的运行时条件创建一个对象
无论采用哪种方式,是否可以将lazy
放在数组类成员中的某个值周围,以便在请求时仅实例化所需的值?或者我必须用闭包或其他方法来解决这个问题
当前尝试
这就是我想的吗?在我得到数组的第一个元素并执行它之前,它实际上不会实例化策略
private var availableStrategies: [() -> (StrategyProtocol)] = [
{ OneClassThatImplementsStrategyProtocol() }
]
我可以回答你的问题。(我不是Swift专家,但元类的使用可能是您想要的,正如我所料,Swift似乎支持它们。)您可以查看这个堆栈溢出
编辑:如果不清楚,我们的想法是让策略数组包含协议的元类,而不是实例化。尽管这取决于您是否希望为具有lazy属性的类的每个实例化都使用一个新的策略对象,或者策略是否是有效的全局策略和创建的缓存策略。如果是后者,那么用于保存它们的惰性数组方法可能会更好。您的“当前尝试”会做您认为它会做的事情。你有一个数组
并且只有在关闭时才初始化策略
执行
一种可能的替代方法是:存储类型数组,而不是
实例或闭包(as)
为了按需创建实例,需要
init()
满足要求的init()
,除非该类是最终的
,
比较)
一个可能的优点是可以查询静态属性
为了找到合适的策略
下面是一个自包含的小示例,其中createStrategy()
创建并返回第一个“奇妙”策略:
protocol StrategyProtocol {
init()
static var isFantastic: Bool { get }
}
class OneClassThatImplementsStrategyProtocol : StrategyProtocol {
required init() { }
static var isFantastic: Bool { return false }
}
final class AnotherThatImplementsStrategyProtocol : StrategyProtocol {
init() { }
static var isFantastic: Bool { return true }
}
class StrategyFactory {
private var availableStrategies: [StrategyProtocol.Type] = [
OneClassThatImplementsStrategyProtocol.self,
AnotherThatImplementsStrategyProtocol.self // etc
]
public func createStrategy() -> StrategyProtocol? {
for strategy in availableStrategies {
if strategy.isFantastic {
return strategy.init()
}
}
return nil
}
}
比较“你认为它做什么”OP可能不清楚数组元素没有被闭包的结果替换,这在我听来就像他在谈论惰性属性时所期待的一样。@Josh Caswell:这不是我的印象(来自“在我获得数组的第一个元素并执行它之前,它实际上不会实例化策略?”)–也许OP可以对此发表评论,如果有必要,我会澄清。我不希望闭包的结果会取代闭包。谢谢你的回答!我最终选择了闭包路线,因为我不喜欢添加inits
,这不是我选择API的直接要求。但是我使用了类型
s这似乎是一个很好的方法,所以我会把它标记为正确的。