DependentMap
DependentMap
是一个 Swift 微框架,定义了一个从键到按键指定的类型的值的集合。
在 Swift 中,Dictionary<KeyType, ValueType>
是一个将键映射到值的集合。它是同质的,即所有键类型相同(此处为 KeyType
),所有值类型相同(此处为 ValueType
)。
通常有一些具有映射语义的类型,其中键类型都相同,但值类型不同。例如,考虑 UserDefaults
。它可以让你用 String
键关联任意值。键关联的值类型取决于调用者。
UserDefaults.standard.set("Alice", forKey: "username")
UserDefaults.standard.set(Date(), forKey: "createDate")
let username = UserDefaults.standard.string(forKey: "username")
let createDate = UserDefaults.standard.object(forKey: "createDate") as? Date
在此,我们在 username
键下添加了一个 String
值,并在 createDate
键下添加了一个 Date
值。但关联值的类型完全由约定定义。要读取它们,您需要知道 username
和 createDate
值的类型。您还需要使用 as?
构造来将 UserDefaults.object(forKey:)
返回的 Any
值转换为 Date
类型,该类型键所引用。
值类型与键关联,但这种类型是隐含的,对编译器来说是未知的。
这就是依赖映射的用途。依赖映射是一种将键映射到值的集合。它允许键指定它们可以关联的值的类型。
在我们的示例中,我们将创建两个键,即 username
和 createDate
,并指定它们的关联值为类型 String
和 Date
。
extension DependentMapKey {
static var username: DependentMapKey<UserDefaults, String, String> {
return .init("username")
}
static var createDate: DependentMapKey<UserDefaults, String, Date> {
return .init("createDate")
}
}
DependentMapKey
声明具有三个类型参数的泛型
- 此键索引的依赖映射的类型。在上述两种情况下,此类型为
UserDefaults
,表明这些键只能用于UserDefaults
实例。 - 原始键类型。这是
String
,因为UserDefaults
使用String
值作为键。将传递给计算属性体中init
函数的原始值类型必须与此类型匹配。 - 此键参考的映射中的值的类型。
username
键引用String
值,而createDate
键引用Date
值。
然后我们可以使用这些键写入和读取 UserDefaults
对象
UserDefaults.standard.set("Alice", for: .username)
UserDefaults.standard.set(Date(), for: .createDate)
let username = UserDefaults.standard.value(for: .username)
let createDate = UserDefaults.standard.value(for: .createDate)
在调用 set(_:for:)
的过程中,编译器确保值的类型与键声明的预期值类型相匹配。同样,编译器能够推断出通过 value(for:)
读取的值的类型,以满足键的声明。
详细信息
框架定义了一个 DependentMapSemantics
协议,该协议要求两个函数:value(for:)
和 set(_:for:)
,用于读取和写入与键关联的值。协议扩展定义了一个索引操作符,以便更简单地进行读取和写入访问。
框架还定义了一个 DependentMapKey<MapType, RawKeyType, ValueType>
类。其中 MapType
参数定义了该键可以用来定义 DependentMapSemantics
类型的类型。参数 RawKeyType
定义了底层集合中的键类型。《code WorthType 定义了键映射到的值类型。
提供了一个扩展到 Dictionary
以添加依赖关系映射语义。注意,此扩展的使用仅限于 Dictionary
实例,其中值为 Any
。
最后,还提供了一个扩展到 UserDefaults
以添加依赖关系映射语义。