我有这个功能:
func flatten<Key: Hashable, Value>(dict: Dictionary<Key, Optional<Value>>) -> Dictionary<Key, Value> {
var result = [Key: Value]()
for (key, value) in dict {
guard let value = value else { continue }
result[key] = value
}
return result
}
如您所见,它将[Key: Value?]
字典转换为[Key: Value]
字典(没有可选的)。
我想用一个新的方法扩展Dictionary
类,只用于值为任何类型的Optional
的类,但是我无法向字典的泛型参数添加约束。
这就是我所尝试的:
extension Dictionary where Value: Optional<Any> {
func flatten() -> [Key: Any] {
var result = [Key: Any]()
for (key, value) in self {
guard let value = value else { continue }
result[key] = value
}
return result
}
}
但失败并出现错误:
Type 'Value' constrained to non-protocol type 'Optional<Any>'
2条答案
按热度按时间xxslljrj1#
在Playground中尝试以下代码:
因为您无法在通信协定扩充的
where
子句中指定确切的类型,所以您可以精确侦测Optional
类型的一种方式是让Optional
“唯一”符合通信协定(例如OptionalEquivalent
)。为了得到
Optional
的 Package 值类型,我在自定义协议OptionalEquivalent
中定义了一个typealiasWrappedValueType
,然后对Optional进行了扩展,将Wrapped
赋值给WrappedValueType
,然后就可以在flat方法中得到该类型。请注意,
sugarCast
方法只是将Optional<Wrapped>
转换为Wrapped?
(完全相同),以启用guard
语句的用法。更新
多亏了Rob纳皮耶的评论,我已经简化并重命名了sugarCast()方法,并重命名了协议,使其更容易理解。
mrwjdhj32#
你可以用一种更简单的方法来做,这适用于Swift 4:
如果你不喜欢使用高阶函数或需要与Swift的早期版本兼容,你也可以这样做: