简介:
我在我的应用程序的某些方面引入了结果框架(反典型)。例如,给定这个函数:
func findItem(byId: Int, completion: (Item?,Error?) -> ());
foo.findItem(byId: 1) { item, error in
guard let item = item else {
// Error case
handleError(error!)
return;
}
// Success case
handleSuccess(item)
}
我用结果来实现它:
func findItem(byId: Int, completion: Result<Item,Error>) -> ());
foo.findItem(byId: 1) { result in
swith result {
case let success(item):
// Success case
handleSuccess(item)
case let failure(error):
// Error case
handleError(error!)
}
}
问题 在成功案例不返回任何内容的情况下,实现结果的正确方法是什么?比如:
func deleteItem(byId: Int, completion: (Error?) -> ());
foo.deleteItem(byId: 1) { error in
if let error = error {
// Error case
handleError(error)
return;
}
// Success case
handleSuccess()
}
在java中我会实现一个结果,在Swift中执行此操作的正确方法是什么
最好的方法正是您所做的:
Error?
,其中nil
表示成功。非常清楚和简单。
也就是说,另一个答案(也是我使用过的答案)正是您的问题:“如何使用 Result 处理 Void 成功案例。”成功案例通过
Void
,所以通过Void
:
Result<Void, Error>
“Void”并不意味着“不返回任何内容”。它是 Swift 中的一种类型,一种只有一个值的类型:空元组
()
。这也恰好是这种类型:
public typealias Void = ()
按照惯例,我们使用
Void
表示类型,使用 ()
表示值。在 Void
中以这种方式使用 Result
有点奇怪的一件事是语法。你最终会得到这样的结果:
return .success(())
双括号有点难看并且有点令人困惑。因此,尽管这与其他使用
Result
的代码非常相似,但在这种情况下我通常只使用 Error?
。不过,如果我有很多,我会考虑为它创建一个新类型:
enum VoidResult {
case success
case failure(Error)
}
您可以添加此扩展程序,以简化您的生活。
public extension Result where Success == Void {
/// A success, storing a Success value.
///
/// Instead of `.success(())`, now `.success`
static var success: Result {
return .success(())
}
}
// Now
return .success
我发现罗布的回答非常有趣和聪明。我只是想贡献一个可能的工作解决方案来帮助其他人:
enum VoidResult {
case success
case failure(Error)
}
/// Performs a request that expects no data back but its success depends on the result code
/// - Parameters:
/// - urlRequest: Url request with the request config
/// - httpMethodType: HTTP method to be used: GET, POST ...
/// - params: Parameters to be included with the request
/// - headers: Headers to be included with the request
/// - completion: Callback trigered upon completion
func makeRequest(url: URL,
httpMethodType: HTTPMethodType,
params: [String:Any],
headers: [String:String],
completion: @escaping (VoidResult) -> Void){
let alamofireHTTPMethod = httpMethodType.toAlamofireHTTPMethod()
let parameterEncoder: ParameterEncoding
switch alamofireHTTPMethod {
case .get:
parameterEncoder = URLEncoding.default
case .post:
parameterEncoder = JSONEncoding.default
default:
parameterEncoder = URLEncoding.default
}
Log.d(message: "Calling: \(url.absoluteString)")
AF.request(url,
method: alamofireHTTPMethod,
parameters: params,
encoding:parameterEncoder,
headers: HTTPHeaders(headers)).response { response in
guard let statusCode = response.response?.statusCode,
(200 ..< 300) ~= statusCode else {
completion(.failure(NetworkFetcherError.networkError))
return
}
completion(.success)
}
}
试试这个
注意这是示例,您可以根据您的测试进行更改
typealias resultHandler = (_ responseItems: AnyObject, _ error: Error) -> Void
func deleteItem(byId: Int, completion: resultHandler){
completion(Items, error)
}
打电话
self.deleteItem(byId: 1) { (result, error) in
if error ==nil{
}
}