【问题标题】:OR clause in swift generics快速泛型中的 OR 子句
【发布时间】:2020-11-12 05:26:14
【问题描述】:

所以,我正在尝试从头开始编写一个网络库,并且我正在尝试利用泛型。

我正在使用 URLComponents 来生成 URL

我的 URLComponent 扩展看起来像这样

 extension URLComponents {
        /*mutating func setQueryItems(params : [Argument<Any>]){
            
            let q = params.map{ item in
               
                if let value = item.valueName.getValue {
                     URLQueryItem(name: item.keyName, value: value)
                }
            }
            
             self.populateQueryItems(queryItems: q)
        }*/
        
        
        mutating func setQueryItems(params : [Argument<Bool>]){
            let q = params.map{ item in
                URLQueryItem(name: item.keyName, value: item.getValue)
            }
            
             self.populateQueryItems(queryItems: q)
        }
        
        mutating func setQueryItems(params : [Argument<Double>]){
            let q = params.map{ item in
                URLQueryItem(name: item.keyName, value: item.getValue)
            }
            
             self.populateQueryItems(queryItems: q)
        }
        
        mutating func setQueryItems(params : [Argument<String>]){
            let q = params.map{ item in
                URLQueryItem(name: item.keyName, value: item.valueName)
            }
            
            self.populateQueryItems(queryItems: q)
        }
        
        mutating private func populateQueryItems(queryItems : [URLQueryItem]){
            if self.queryItems == nil {
                self.queryItems = queryItems
            }else {
                self.queryItems?.append(contentsOf: queryItems)
            }
        }
    }

这是我的参数结构

struct Argument<T> {
    var keyName : String
    var valueName : T
}

extension Argument where T == Int {
    var getValue : String{
        return valueName.description
    }
}

extension Argument where T == Double {
    var getValue : String{
        return valueName.description
    }
}

extension Argument where T == Bool {
    var getValue : String{
        return valueName.description
    }
}

如您所见,在 URLComponent 的扩展中,函数 setQueryItems 被多次重载,具有相同的主体,因为 Argument 的 Type T 不同。我需要想办法摆脱这种混乱。

我想是否有办法在 where 子句中包含 OR 逻辑,但没有这样的办法。

如何改进这个逻辑并删除冗余代码?

【问题讨论】:

    标签: ios xcode generics swift5


    【解决方案1】:

    在这种情况下,泛型是错误的方法。

    Argument 的泛型类型的共同点是协议CustomStringConvertible,所有采用该协议的类型都有一个description 属性。

    声明结构非泛型

    struct Argument {
        var keyName : String
        var valueName : CustomStringConvertible
        
        var value : String { return valueName.description }
    }
    

    URLComponents 扩展名可以缩减为

    extension URLComponents {
        mutating func setQueryItems(params : [Argument]){
            let q = params.map{ item in
                URLQueryItem(name: item.keyName, value: item.value)
            }
            self.populateQueryItems(queryItems: q)
        }
        
        mutating private func populateQueryItems(queryItems : [URLQueryItem]){
            if self.queryItems == nil {
                self.queryItems = queryItems
            }else {
                self.queryItems?.append(contentsOf: queryItems)
            }
        }
    }
    

    编辑:

    如果您还想考虑数组,则必须扩展 value 属性,例如

    struct Argument {
        var keyName : String
        var valueName : CustomStringConvertible
        
        var value : String {
            if let valueArray = valueName as? [CustomStringConvertible] {
                return valueArray.map{$0.description}.joined(separator: "-")
            } else {
                return valueName.description
            }
        }
    }
    

    【讨论】:

    • 好的,这看起来很合理,但是如果我需要以特定方式将数组传递给 URLComponents 的 queryItems,比如 [1,2,3] 必须显示为 1-2- 3?
    猜你喜欢
    • 2023-03-22
    • 2016-11-17
    • 2019-08-20
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多