ios - 快速泛型中的 OR 子句
问题描述
所以,我正在尝试从头开始编写一个网络库,并且我正在尝试利用泛型。
我正在使用 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 逻辑,但没有这样的方法。
如何改进此逻辑并删除冗余代码?
解决方案
在这种情况下,泛型是错误的方法。
泛型类型的共同点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
}
}
}
推荐阅读
- python - 如何将自定义类及其变量/方法添加到 Visual Studio Intellisense?
- javascript - 如何在php中获取参数
- google-apps-script - 如何将数据复制到新的电子表格然后另存为 PDF?
- c# - 如何在 Windows Server 2012 R2 上运行 Microsoft.CognitiveServices.Speech
- c# - 无法加载程序集 UnityEngine.UI 的文件,编辑器 UI 在运行时也有问题
- javascript - 不等于!= Google App 脚本不起作用
- maven - 当我使用 selenium 使用 maven 运行 testng 时出现错误
- visual-studio-code - 如何在 Visual Studio Code 中禁用“假”右括号注释?
- c++ - 如何结束 COM 自动化期间执行的进程
- javascript - 手动设置边缘的路由点 (mxGraph)