制作Swift字典,键是“Type”?

时间:2017-02-25 17:48:06

标签: swift dictionary types

我正在尝试做这类事情。

static var recycle: [Type: [CellThing]] = []

但是 - 我不能:)。

enter image description here

  

未声明的类型'类型'

在示例中,CellThing是我的基类,因此A:CellThingB:CellThingC:CellThing等等。我的想法是在字典数组中存储各种A A A,B B,C C C C.

如何制作“类型”(理想情况下我猜,限制为CellThing)是Swift词典中的关键

我很感激我可能(也许?)使用String(describing: T.self),但这会让我失眠。

这是一个用例,设想的代码看起来像这样......

@discardableResult class func make(...)->Self {
  return makeHelper(...)
  }

private class func makeHelper<T: CellThing>(...)->T {
  let c = instantiateViewController(...) as! T
  return c
  }

那么就像......

static var recycle: [Type: [CellThing]] = []

private class func makeHelper<T: CellThing>(...)->T {
  let c = instantiateViewController(...) as! T

  let t = type whatever of c (so, maybe "A" or "B")
  recycle[t].append( c )

  let k = recycle[t].count
  print wow, you have k of those already!

  return c
  }

3 个答案:

答案 0 :(得分:18)

不幸的是,元类型类型目前不可能符合协议(请参阅this related question) - 因此CellThing.Type目前不符合Hashable,也不能符合Key。因此,这意味着它不能直接用作Dictionary的{​​{1}}。

但是,您可以使用ObjectIdentifier为元类型创建包装器,以便提供Hashable实现。例如:

/// Hashable wrapper for a metatype value.
struct HashableType<T> : Hashable {

  static func == (lhs: HashableType, rhs: HashableType) -> Bool {
    return lhs.base == rhs.base
  }

  let base: T.Type

  init(_ base: T.Type) {
    self.base = base
  }

  func hash(into hasher: inout Hasher) {
    hasher.combine(ObjectIdentifier(base))
  }
  // Pre Swift 4.2:
  // var hashValue: Int { return ObjectIdentifier(base).hashValue }
}

class CellThing {
  // Convenience static computed property to get the wrapped metatype value.
  static var hashable: HashableType<CellThing> { return HashableType(self) }
}

class A : CellThing {}
class B : CellThing {}

var recycle: [HashableType<CellThing>: [CellThing]] = [:]

recycle[A.hashable] = [A(), A(), A()]
recycle[B.hashable] = [B(), B()]

print(recycle[A.hashable]!) // [A, A, A]
print(recycle[B.hashable]!) // [B, B]

这也适用于泛型,你只需用T.hashable代替你的字典。

答案 1 :(得分:1)

如果扩展Dictionary type,则可以直接使用已经定义的通用Key

extension Dictionary {
    // Key and Value are already defined by type dictionary, so it's available here
    func getSomething(key: Key) -> Value {
        return self[key]
    }
}

之所以可行,是因为Dictionary已为自己使用定义了泛型KeyValue

答案 2 :(得分:-4)

希望AnyHashable有所帮助。但它出现在 Xcode 8.0

您可以执行以下操作:

var info: [AnyHashable : Any]? = nil