我有一个typealias:
typealias BeaconId = [String: NSObject]
我希望通过以下方式扩展它:
extension BeaconId {}
但这会引发编译错误:
必须在非专业化的通用类型'词典'上声明约束扩展名。具有由'其中'指定的约束。条款
所以我最终做了:
extension Dictionary where Key: StringLiteralConvertible, Value: NSObject {}
有更清洁的方法吗?
答案 0 :(得分:4)
AFAIK,没有。
考虑以下示例:
typealias Height: Float
extension: Height {
}
此处Height
不是新类型,它只是Float
的标签,因此您只是在扩展Float
。如果您查看Dictionary
它public struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible
那么您想要实现的目标
extension BeaconID {}
正在为Dictionary
添加具有特定通用参数的扩展程序。
我期望您能够做到的是:
typealias BeaconID = Dictionary<Key: String, Value: NSObject>
但这也没有编译,因为在Swift中你不能输入部分类型(换句话说,没有特定通用参数类型的泛型类型。请参阅here了解更多信息信息)。类型化通用类型的可能解决方法,在我链接的答案下面是
struct Wrapper<Key: Hashable, Value> {
typealias T = Dictionary<Key, Value>
}
typealias BeaconID = Wrapper<String, NSObject>.T
但即便如此,当您尝试扩展BeaconID
时,您会收到编译器警告,最终会触及问题的核心:
&#34;必须在非专业化的通用类型&#39;词典&#39;上声明约束扩展名。具有由&#39;其中&#39;指定的约束。条款&#34;
答案 1 :(得分:1)
在Swift 4.2时进行更新: 您现在可以执行此操作
示例:
typealias KeyedNumbers = [String: Int]
extension KeyedNumbers {
func squaredValue(forKey key: String) -> Int {
return self[key]! * self[key]!
}
}
有了这个(几乎没有用的)扩展名,您可以执行以下操作:
let pairs = ["two": 2, "three": 3]
print("2 squared =", pairs.squaredValue(forKey: "two"))
它将打印
2平方= 4