我正在建造一个农场,那里所有可以生长的东西都符合可生长协议。当你种植一种植物时,你称它为“功能”:
myFarm.planting<T: Growable>(qty: Int, of: T.Type) -> Farm
现在,我希望农场的每个实例都有一个字典实例var,如下所示:
var crops = [Growable.Type: Int]
问题是,即使我使Growable协议继承Hashable,这也无助于Growable类型成为Hashable。
换句话说,即使我向Growable添加了如下扩展:
extension Growable {
static func hashValue {
// return some hash
}
}..。但是,Growable类型是不可接受的,因为Hashable协议只涉及类型的实例,而不涉及类型本身。
好吧,通常我会放弃,说:“我太蠢了,别再这样做了。”
然而,这是Swift,所以我想一定有一种方法可以使语言顺应我的意愿,无论是制定一个新的StaticHashable协议,然后用新的下标方法扩展字典类型,接受它,或者修改Swift的源代码本身,然后向进化论列表做一个介绍。
但在我走上这两条路之前,我认为明智的做法是问你们天才们是否已经有办法去做我想做的事,或者这样做是否非常愚蠢,你会给我一个明显优越的方法,那就是我一直以来都是愚蠢得令人难以置信的愚蠢。
注意:我的观点是,类型本身应该能够静态地遵守其功能不被声明为静态的协议,因为为什么消息的发送方应该关心响应的实体是不朽的上帝还是以某种上帝的形象创建的短暂的生物?
发布于 2017-10-18 19:58:28
是否可以在Swift中使用Type作为字典键?
这是可能的,这里有一种方法:
protocol Growable { ... }
struct S : Growable { ... }
class C : Growable { ... }
extension Dictionary where Key : LosslessStringConvertible
{
subscript(index: Growable.Type) -> Value?
{
get
{
return self[String(describing: index) as! Key]
}
set(newValue)
{
self[String(describing: index) as! Key] = newValue
}
}
}
var d : [String:Int] = [:]
d[S.self] = 42
d[C.self] = 24
print(d)指纹:
["C": 24, "S": 42]如果将subscript定义更改为:
subscript(index: Any.Type) -> Value?当然,您可以使用任何类型作为键:
var d : [String:Int] = [:]
d[S.self] = 42
d[C.self] = 24
d[type(of:d)] = 18
print(d)指纹:
["C": 24, "S": 42, "Dictionary<String, Int>": 18]我让你来决定这是否明智,但这显然是可能的。
[注意:您不能将Key限制为String,因此使用协议LosslessStringConvertible__;可能有更好的选择,Swift标准库是一个移动目标.]
HTH
发布于 2017-10-18 19:35:27
你可以考虑后退一步,回顾一下你的设计。您可以使用枚举(另一个强大的Swift功能)对Growable工厂进行建模。例如:
protocol Growable {
/* ... */
}
enum Vegetable: String, Hashable, Growable {
case carrot, lettuce, potato /* ... */
}
enum Mushroom: String, Hashable, Growable {
/* ... */
}
struct Farm {
var crops = [AnyHashable: Int]()
mutating func plant<T: Growable & Hashable>(qty: Int, of growable: T) {
crops[growable] = qty
}
}不支持使用Hashable作为具体类型,因此,我们需要使用类型擦除的AnyHashable结构来代替--具有自或相关类型需求的协议可能很难得到正确的处理!
用法:
var myFarm = Farm()
myFarm.plant(qty: 10, of: Vegetable.carrot)
myFarm.plant(qty: 20, of: Vegetable.lettuce)
myFarm.plant(qty: 30, of: Vegetable.potato)
print(myFarm.crops)AnyHashable(Vegetable.potato):30,AnyHashable(Vegetable.carrot):10,AnyHashable(Vegetable.lettuce):20
和.关于你最初的设计,正确的表达你意图的方法是:
extension Growable.Type: Hashable {
/* make this meta thing hashable! */
}也就是说,制作相应的元类型Hashable,但Swift还不支持扩展元类型;)
https://stackoverflow.com/questions/46814089
复制相似问题