gpt4 book ai didi

swift - 为什么 Enum 作为协议(protocol)要求中的可选行为表现得很奇怪?

转载 作者:行者123 更新时间:2023-11-30 11:35:04 26 4
gpt4 key购买 nike

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

当我将其移至协议(protocol)本身时,我收到错误:

Type 'MyResource' does not conform to protocol '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
}
}

然后我初始化了MyResourceMyAPIRequest如:

let apiResource = MyResource()
let apiRequest = MyAPIRequest(resource: apiResource)
apiRequest.load {
// async task with completion block
}
<小时/><小时/>

所以,我的问题是:

  • 为什么在扩展中添加属性一开始不起作用?
  • 为什么它在添加到协议(protocol)定义本身时会起作用?
  • 最后,为什么我被迫使用注释rawValue初始化器?

最佳答案

  1. 如果我们在扩展中定义任何属性并且不在协议(protocol)中声明它,那么它只会获取扩展值。您是否重新定义它并不重要。

  2. 当您在协议(protocol)中定义它时,它就可以被覆盖,因此您可以获得子值。

  3. 这里的声明是可选的,并且您在其中传递非可选值。所以你必须告诉值的类型。

希望这有帮助。

关于swift - 为什么 Enum 作为协议(protocol)要求中的可选行为表现得很奇怪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49852065/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com