【问题标题】:specialized extension of Dictionary词典的专门扩展
【发布时间】:2015-10-13 05:19:14
【问题描述】:

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

我试过这个:

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,但仅限于Dictionary&lt;String, String&gt;

非常感谢任何帮助。

编辑

正如@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)
    }
}

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

【问题讨论】:

    标签: swift generics


    【解决方案1】:

    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 :)

    【讨论】:

    • 我明白了。有没有办法将扩展限制为 String 类型?没有声明新协议?或制作字符串以采用协议?像extension Dictionary where Key : String, Value: String { .... 这样的东西对我来说是理想的
    • 我想将一个字符串字典编码成一个查询字符串。我认为 NSURLComponents 是相反的。
    • 相反:let comps = NSURLComponents(); comps.queryItems = [NSURLQueryItem(name: "foo", value: "bar")]; comps.percentEncodedQuery // returns "foo=bar"
    • 谢谢!我找到了一种正确声明它的方法,但是使用 NSURLComponents 我认为我不需要它。谢谢:)
    • 好吧..想想当你的键或值包含=&amp; 字符时会发生什么...
    猜你喜欢
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    相关资源
    最近更新 更多