Swift 制作一本快捷字典,其中的关键是;“类型”是什么;?
我正试着做这种事Swift 制作一本快捷字典,其中的关键是;“类型”是什么;?,swift,dictionary,types,Swift,Dictionary,Types,我正试着做这种事 static var recycle: [Type: [CellThing]] = [] 但是——我不能:) 未声明的类型“type” 在这个例子中,CellThing是我的基类,所以A:CellThing,B:CellThing,C:CellThing等等。我的想法是将各种A、B、C存储在字典数组中 如何使一个“类型”(理想情况下,我想,限制在手机上)成为Swift字典的关键 我很感激我能(也许?)使用String(description:T.self),但那会让我失眠
static var recycle: [Type: [CellThing]] = []
但是——我不能:)
未声明的类型“type”
在这个例子中,CellThing
是我的基类,所以A:CellThing
,B:CellThing
,C:CellThing
等等。我的想法是将各种A、B、C存储在字典数组中
如何使一个“类型”(理想情况下,我想,限制在手机上)成为Swift字典的关键
我很感激我能(也许?)使用String(description:T.self)
,但那会让我失眠
这是一个用例,设想的代码看起来像这样
@discardableResult class func make(...)->Self {
return makeHelper(...)
}
private class func makeHelper<T: CellThing>(...)->T {
let c = instantiateViewController(...) as! T
return c
}
@discardableResult类func make(…)->Self{
返回makeHelper(…)
}
私有类func makeHelper(…)->T{
设c=实例化eviewController(…)为!T
返回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
}
static var recycle:[Type:[CellThing]]=[]
私有类func makeHelper(…)->T{
设c=实例化eviewController(…)为!T
设t=c的任何类型(因此,可能是“A”或“B”)
回收[t]。追加(c)
设k=recycle[t]。计数
打印哇,你已经有k个了!
返回c
}
不幸的是,目前元类型不可能符合协议(请参阅相关内容)–因此CellThing.Type
目前不符合,也不能符合哈希表。因此,这意味着它不能直接用作词典
的键
但是,您可以使用为元类型创建包装器,以便提供可散列的实现。例如:
/// 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 {}
class A : CellThing {}
class B : CellThing {}
var recycle: [HashableType<CellThing>: [CellThing]] = [:]
recycle[A.self] = [A(), A(), A()]
recycle[B.self] = [B(), B()]
print(recycle[A.self]!) // [A, A, A]
print(recycle[B.self]!) // [B, B]
将触发字典中存储的数组的O(N)副本
这是一个旨在通过解决的问题,已在Swift 5中作为非官方语言功能实现。如果您对使用非官方语言特性感到满意,并且该特性可能会在将来的版本中出现(不推荐用于生产代码),那么您可以将下标实现为:
extension Dictionary {
subscript<T>(key: T.Type) -> Value? where Key == HashableType<T> {
get { return self[HashableType(key)] }
_modify {
yield &self[HashableType(key)]
}
}
}
扩展字典{
下标(key:T.Type)->Value?其中key==HashableType{
获取{return self[HashableType(key)]}
_修改{
yield和self[哈希表类型(键)]
}
}
}
它解决了性能问题,允许数组值在字典中进行适当的变异
否则,一个简单的替代方法是不定义自定义下标,而是在类型上添加一个方便的computed属性,以便将其用作键:
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]
类细胞{
//方便静态计算属性获取包装的元类型值。
静态变量hashable:HashableType{return HashableType(self)}
}
A类:细胞{}
B类:细胞{}
var recycle:[HashableType:[CellThing]=[:]
回收[A.hashable]=[A(),A(),A()]
回收[B.hashable]=[B(),B()]
打印(循环使用[A.hashable]!)/[A,A,A]
打印(循环使用[B.hashable]!)/[B,B]
希望有帮助。但它出现在Xcode 8.0中
您可以执行以下操作:
var info: [AnyHashable : Any]? = nil
如果扩展,则可以直接使用已定义的通用键
extension Dictionary {
// Key and Value are already defined by type dictionary, so it's available here
func getSomething(key: Key) -> Value {
return self[key]
}
}
这是因为字典已经为自己的使用定义了泛型键
和值
。您尝试过CellThing.selfAre类型可哈希吗?@matt-我很感激我可能必须使CellThing可哈希。这真的是问题所在吗(错误很奇怪)?是的。它正在寻找一个名为Type的类,但没有。我可以使用类作为非静态变量的键:var recycle:[UIView.self:[String]]=[]//没有编译器错误我也不知道AnyHashable
会有什么帮助;它只能包装可散列的
事物,但元类型不是可散列的
。因此,回顾一下问题标题(1)那里的元类型实际上是:CellThing.Type
(2)然而,实际上在Swift中,您不能使元类型可散列:就是这样。谁知道呢?@JoeBlowCellThing.Type
是元类型类型,它是类型的类型(而CellThing.self
是元类型值,它的一个实例)。当前无法将元类型直接与协议一致。请参阅。@matt元类型值只是指向给定类型的底层元类型信息的指针–ObjectIdentifier
只是使用这些指针值(您可以看到它只是转换到内置.RawPointer
)来给您一个hashValue
实现(通过一个简单的身份比较实现平等)。我很抱歉打断了这么一个老话题,但我只是想知道,如果CellThing
不是一个基类,而是一个协议,有没有办法让你的答案起作用?当我尝试时,Swift告诉我不能为“[HashableType:[CellThing]”类型的值下标'使用类型为'A.type'的参数打印(回收[A.self]!)
@谢谢你的问题。我也有同样的问题。你找到解决方案了吗?不过,type
不是可散列的
seven,谢谢-我不确定这是否解决了问题,因为我不再理解我写的问题:)我得考虑一下。问哈米什:)@Fattie——我读到的问题是,我怎样才能写出一些需要泛型并在字典上运行的东西。最简单的方法(至少对我来说)就是扩展字典。@sevenseven不完全-问题是如何使用元类型作为字典键,例如,如何编写类似于[String.self:“hello”]
或dict[String.self]=“hello”
的内容。话虽如此,使用字典扩展的想法让我了解了如何定义一个方便的下标,以便为您在HashableType
中装箱元类型:)
var info: [AnyHashable : Any]? = nil
extension Dictionary {
// Key and Value are already defined by type dictionary, so it's available here
func getSomething(key: Key) -> Value {
return self[key]
}
}