字典

时间:2015-07-23 04:38:13

标签: swift generics

如何声明仅适用于特定类型的扩展程序?

我试过了:

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 

我收到错误:

  

无法调用&quot; queryString&#39;没有参数

这里有什么问题?我希望能够在词典上调用queryString,但仅限于Dictionary<String, String>

非常感谢任何帮助。

修改

正如@jtbandes所说,String不符合CustomStringConvertibleCustomStringConvertible Protocol Reference建议使用String()构造函数来获取字符串,而不是将协议用作约束。

  

注意:String(instance)适用于任何类型的实例,如果实例恰好是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)
    }
}

EDIT2

这是我的最终版本。

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!
    }
}

1 个答案:

答案 0 :(得分:5)

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 ...

但实际上,我认为您可能需要查看NSURLQueryItemNSURLComponents:)