Adding mutable static properties to Generics and Protocol extensions


In Swift we currently are not able to add static mutable properties to Generic types. If we try to do this the compiler will give us an error Static stored properties not supported in generic types


However there is a solution to this:


fileprivate var _gValues: [ObjectIdentifier: Any] = [:]

struct MyValue<T> {
    static var a: Int {
        get {
            _gValues[ObjectIdentifier(Self.self)] as? Int ?? 42
        }

        set {
            _gValues[ObjectIdentifier(Self.self)] = newValue
        }
    }
}


Here we use the ObjectIdentifier function that provides a stable Hashable value for each generic concrete type.


We can also use this solution to create mutable static properties in extensions, including extensions to protocol types were the value storage is local to the final concrete type that conforms to the protocol:


protocol LocalStore {
    associatedtype StoredValue
    static var defaultValue: StoredValue { get }
    static var cache: StoredValue { get set }
}

extension LocalStore {
    static var cache: StoredValue {
        get {
            _gValues[ObjectIdentifier(Self.self)] as? StoredValue ?? defaultValue
        }
        set {
            _gValues[ObjectIdentifier(Self.self)] = newValue
        }
    }
}


Types that conform to this protocol just need to define a read-only default value, this can be a computed property so can be defined in the extension that provides conformance.