【问题标题】:How to restrict a Swift extension of a collection to a generic type?如何将集合的 Swift 扩展限制为泛型类型?
【发布时间】:2020-03-01 00:11:27
【问题描述】:

因为元组在 Swift 中不可散列,所以我创建了一个通用结构 Couple 来包含两个元素,它们组合起来可以用作字典的键。

struct Couple<U: Hashable, V: Hashable>: Hashable {
    let u: U
    let v: V

    init( _ u: U, _ v: V ) {
        self.u = u
        self.v = v
    }
}
var dictionary: [ Couple<Int,Int> : Any ] = ...

现在,我想使用 Couple 来扩展 Dictionary。

extension Dictionary where Key == Couple<U: Hashable, V: Hashable>, Value == Any {
    func exampleConvertToArray() -> [ ( U, V, Any ) ] {
    }
}

无论我在扩展语句中如何引用 Couple, U, V,编译器都会报错。如果我改为将泛型添加到函数定义中,编译器也会报错。

如果类型不是通用的 (extension Dictionary where Key == Couple&lt;Int, Int&gt;, Value == Any),一切都很好。

如何创建这个通用扩展?

【问题讨论】:

  • 旁注:不要将Value 锁定为Any。如果消费者想要使用Any 值,他们已经可以这样做了。
  • 如果您希望两个元素具有相同的类型,则无需创建两个通用的可散列类型。
  • struct Couple&lt;H: Hashable&gt;: Hashable { 987654329 init( _ left: H, _ right: H) { 987654331 self.right = right 987654333 } 987654335 func exampleConvertToArray&lt;H&gt;() -&gt; [(H, H, Any)] where Key == Couple&lt;H&gt; { 987654337 } 987654339 @ 跨度>
  • 顺便说一句,我认为更好的结构命名是Pair

标签: swift dictionary generics extension-methods


【解决方案1】:

这是可能的,但不幸的是,通用约束必须在成员本身上表达,而不是在整个extension

struct Couple<U: Hashable, V: Hashable>: Hashable {
    let u: U
    let v: V

    init( _ u: U, _ v: V ) {
        self.u = u
        self.v = v
    }
}

extension Dictionary {
    func exampleConvertToArray<U, V>() -> [(U, V, Any)] where Key == Couple<U, V> {
        self.map { (key, value) in (key.u, key.v, value) }
    }
}

let input = [
    Couple(1, 2): 3,
    Couple(4, 5): 6,
    Couple(7, 8): 9,
]

let result = input.exampleConvertToArray()
print(result)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 2018-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多