我想知道Swift 3编程语言中是否有一个构造允许我将一些对象存储在一个数组中,但是懒惰地初始化该数组中的每个元素。
想象一下这个示例类:
class A {
let test = "hello"
let test2 = 2.0
}
现在我想存储一个' A'另一个类的数组中的对象,如下所示:
class B {
var lazy(?) array: [A] = {
// Some code to initialize the element being accessed
}()
}
如果我现在访问任何元素,如果在我访问它时初始化它会很酷,所以很懒散
print(B.array[1].test) (element at index one is now initialized)
这可能吗?
答案 0 :(得分:2)
您可以使用lazy
支持A
后备存储,该存储在首次访问时实例化,例如:
class Astorage {
/* ... lots of ... */
let id: Int
var foo: String = "bar"
init(_ id: Int) {
self.id = id
print("Initializing backing storage for A with id \(id)")
// ...
}
}
class A {
private let id: Int
lazy var storage: Astorage = Astorage(self.id)
init(_ id: Int) {
self.id = id
}
}
class B {
var array: [A]
init (_ array: [A]) {
self.array = array
}
}
let b = B((1...5).map(A.init))
b.array[2].storage.foo = "foo"
// Initializing backing storage for A with id 3
b.array[4].storage.foo = "bax"
// Initializing backing storage for A with id 5
答案 1 :(得分:2)
您可以使用enum
和mutating
struct
来实现此目标
enum LazyValueEnum<T>: CustomStringConvertible {
case value(T)
case thunk((Void) -> T)
var forceValue: T {
switch self {
case .value(let t):
return t
case .thunk(let thunk):
return thunk()
}
}
var description: String {
switch self {
case .value(let t):
return String(describing: t)
case .thunk(_):
return "<thunk>"
}
}
}
struct LazyValue<T>: CustomStringConvertible {
var value: LazyValueEnum<T>
init(_ t: T) {
self.value = .value(t)
}
init(lazy thunk: @escaping (Void) -> T) {
self.value = .thunk(thunk)
}
static func lazy(_ thunk: @escaping (Void) -> T) -> LazyValue<T> {
return LazyValue(lazy: thunk)
}
static func value(_ value: T) -> LazyValue<T> {
return LazyValue(value)
}
mutating func forceValue() -> T {
let t = value.forceValue
value = .value(t)
return t
}
var description: String {
return value.description
}
}
var a: [LazyValue<Int>] = [.value(5), .value(7), .lazy { Int(arc4random()) }]
print(a)
print(a[2].forceValue())
print(a)
print(a[2].forceValue())
print(a)