Is there a way to have a static variable, which throws, that we initialize on first run and cache for future runs? Right now, it’s written as below, which works, but is a little convoluted.
public static var shared: Object {
get throws {
if let singleton = Self.singleton {
return singleton
}
Self.singleton = try Object()
return Self.singleton!
}
}
private static var singleton: Object? = nil
Ideally, I want this to be something like:
public static let singleton: Object {
get throws {
if (singleton is uninitialized) { return try Object() }
else { return (previously initialized object) }
}
}
For someone interested in doing the work, I think it would be reasonable to allow global or static let properties to be throws and/or async when their initializer throws. lazy var instance properties could as well.
I'd like to highlight a subtlety in semantics here.
The original code from Winston attempts to create the object at every call of the getter until one call produces an object instead of an error.
If instead you're willing to go the route of doing a single attempt, remembering the error if one was thrown, this would be much simpler:
static private let _shared = Result { try Object() }
static public var shared: Object {
get throws { try _shared.get() }
}
I think if this was supported as a language feature I would expect the behavior I wrote above where you get only one try and it remembers the result including the error. There's certainly cases where you want the retry-at-every-call-until-it-works approach, but it'd be very surprising to me if a global or static variable initializer got called more than once.