【发布时间】:2018-04-16 07:48:48
【问题描述】:
enum 我已经:
enum APIMethod: String {
case GET
case POST
}
我将protocol 定义为:
protocol APIResource {
associatedtype Model: Codable
var base: String { get }
var path: String { get }
}
extension APIResource {
var method: APIMethod? { // To be able to have the conforming type ignore if it wants
return nil // Actually, this will return a valid case but not now
}
var request: URLRequest {
let url = URL(string: base + path)!
var request = URLRequest(url: url)
request.httpMethod = method?.rawValue
return request
}
}
现在,当我在我的 struct 中采用它时,我会提供它自己的 method,例如:
struct MyResource: APIResource {
typealias Model = MyCodableModelStructure
let base = "http://---.com"
let path = "/pathToResource"
let method = APIMethod.POST
}
但是在计算 request 属性时,request.httpMethod 不会得到 "POST" 的值。
然后我尝试做一些不同的事情。我将enum 要求从extension 移到protocol 本身。
protocol APIResource {
associatedtype Model: Codable
var base: String { get }
var path: String { get }
var method: APIMethod? { get }
}
extension APIResource {
var request: URLRequest {
let url = URL(string: base + path)!
var request = URLRequest(url: url)
request.httpMethod = method?.rawValue
return request
}
}
当我将它移到协议本身时,我得到了错误:
类型
'MyResource'不符合协议'APIResource'
所以我不得不将MyResource重新定义为:
struct MyResource: APIResource {
typealias Model = MyCodableModelStructure
let base = "http://---.com"
let path = "/pathToResource"
// See! I was forced to annotate the type
let method: APIMethod? = APIMethod.POST
// Or, otherwise, I tried with rawValue without annotating the type
// let method = APIMethod(rawValue: "POST")
}
此时,request 属性与request.httpMethod = "POST" 成功计算。
编辑:
实际上我的APIResource 有一个associatedtype。因此,我创建了一个通用类:
class MyAPIRequest<T: APIResource> {
let resource: T
init(resource: T) {
self.resource = resource
}
}
然后我将MyResource和MyAPIRequest初始化为:
let apiResource = MyResource()
let apiRequest = MyAPIRequest(resource: apiResource)
apiRequest.load {
// async task with completion block
}
所以,我的问题是:
- 为什么一开始在扩展中添加属性不起作用?
- 为什么它在添加到协议定义本身时会起作用?
- 最后,为什么我不得不使用 annotating 或
rawValue初始化器?
【问题讨论】:
-
把
let method: APIMethod?改成var method: APIMethod? -
但是在计算请求属性时,request.httpMethod 没有得到值“POST”。我根本没有经历过这种行为......你也可以吗请展示如何实例化该结构?
-
@holex 查看我的编辑
-
@CZ54 基本上不能解决我遇到的问题。
let或var都不会让我摆脱类型注释。
标签: swift enums swift-protocols