加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 向扩展中的通用参数添加约束

发布时间:2020-12-14 05:19:59 所属栏目:百科 来源:网络整理
导读:我有这个功能: func flattenKey: Hashable,Value(dict: DictionaryKey,OptionalValue) - DictionaryKey,Value { var result = [Key: Value]() for (key,value) in dict { guard let value = value else { continue } result[key] = value } return result}
我有这个功能:
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类,只有这个类的值是任何类型的可选项,但是我无法为字典的通用参数添加约束.

这是我试过的:

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>'
在游乐场尝试此代码:
// 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"]

因为您不能在协议扩展的where子句中指定确切类型,所以您可以精确检测可选类型的一种方法是使可选UNIQUELY符合协议(例如OptionalEquivalent).

为了获取可选的包装值类型,我在自定义协议OptionalEquivalent中定义了一个typealias WrappedValueType,然后将可扩展的可扩展名,将“Wrapped”绑定到WrappedValueType,然后可以在flatten方法中获取类型.

请注意,sugarCast方法只是将可选的< Wrapped>要包装?(这是完全一样的),以启用使用保护语句.

UPDATE

感谢Rob Napier的评论,我简化了&更名为sugarCast()方法,并重命名协议,使其更易于理解.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读