如何声明只对特定类型有效的扩展?
我试过这个:
extension Dictionary where
Key : CustomStringConvertible,
Value: CustomStringConvertible
{
func queryString() -> String {
var paramArray = Array<String>()
for (key, value) in self {
paramArray.append("\(key.description)=\(value.description)")
}
return "&".join(paramArray)
}
}
它编译得很好。但是当我尝试使用它的时候
var d = Dictionary<String, String>()
var q = d.queryString() // <-- ERROR
我得到错误:
无法在没有参数的情况下调用“querystring”
这里怎么了?我希望能够在字典上调用
queryString
任何帮助都非常感谢。
编辑
正如@jtbandes所说,
Dictionary<String, String>
不符合String
。CustomStringConvertible Protocol Reference建议使用CustomStringConvertible
构造函数获取字符串,而不是使用协议作为约束。注意:字符串(实例)适用于任何类型的实例,如果该实例恰好是CustomStringConvertible,则返回其说明。因此,不鼓励将CustomStringConvertible用作泛型约束,或直接访问一致类型的描述。
extension Dictionary {
public func queryString() -> String {
var paramArray = Array<String>()
for (key, value) in self {
paramArray.append("\(String(key))=\(String(value))")
}
return "&".join(paramArray)
}
}
编辑2
这是我的最终版本。
extension Dictionary {
public func queryString() -> String {
var queryItems = Array<NSURLQueryItem>()
for (key, value) in self {
queryItems.append(NSURLQueryItem(name: String(key), value: String(value)))
}
let comps = NSURLComponents();
comps.queryItems = queryItems
return comps.percentEncodedQuery!
}
}
最佳答案
String
不是CustomStringConvertible
。您可以使用:
extension String: CustomStringConvertible {
public var description: String { return self }
}
或者,我建议为这种情况制定自己的协议:
protocol QueryStringConvertible {
var queryStringRepresentation: String { get }
}
extension String: QueryStringConvertible {
var queryStringRepresentation: String { return self /*probably should escape the string here*/ }
}
extension Dictionary where
Key : QueryStringConvertible,
Value : QueryStringConvertible ...
但实际上,我认为你可能想看看NSURLQueryItem和NSURLComponents:)