で汎用パラメータに制約を追加します。私はこの機能を持っている拡張
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?]
辞書を変換します。
Optional
の値を持つクラスに対してのみ、新しいメソッドでDictionary
クラスを拡張したいと考えましたが、辞書の汎用パラメータに制約を追加できません。
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
}
}
しかし、エラーで失敗します:
これは私が試したものですあなたが正確な型を指定することはできませんので
// make sure only `Optional` conforms to this protocol
protocol OptionalEquivalent {
typealias WrappedValueType
func toOptional() -> WrappedValueType?
}
extension Optional: OptionalEquivalent {
typealias WrappedValueType = Wrapped
// just to cast `Optional<Wrapped>` to `Wrapped?`
func toOptional() -> WrappedValueType? {
return self
}
}
extension Dictionary where Value: OptionalEquivalent {
func flatten() -> Dictionary<Key, Value.WrappedValueType> {
var result = Dictionary<Key, Value.WrappedValueType>()
for (key, value) in self {
guard let value = value.toOptional() else { continue }
result[key] = value
}
return result
}
}
let a: [String: String?] = ["a": "a", "b": nil, "c": "c", "d": nil]
a.flatten() //["a": "a", "c": "c"]
:
Type 'Value' constrained to non-protocol type 'Optional<Any>'
をより簡単に'sugarCast()'を 'return self'として実装してください。私は個人的にこのプロトコルを 'OptionalConvertible'と' sugarCast() '' toOptional() 'と呼ぶことをお勧めしますが、あなたのやり方も問題ありません。 –
あなたが正しいです、私は自分のコードを更新します – cezheng
これは、一般的な制限を回避する非常に創造的な方法です。私はおそらくもっと多くの場所でそれを使用します。ありがとう – redent84