【问题标题】:How to handle Void success case with Result lib (success/failure)如何使用 Result lib 处理 Void 成功案例(成功/失败)
【发布时间】:2017-05-19 10:07:03
【问题描述】:

简介

我在我的应用程序的某些地方引入了Result framework (antitypical)。例如,给定这个函数:

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

我用 Result 来实现它:

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 中我会实现一个 Result 在 Swift 中执行此操作的正确方法是什么

【问题讨论】:

  • 这里有什么问题吗?
  • 如何使用Result实现第二个例子
  • 仍然没有收到您的问题。

标签: ios swift


【解决方案1】:

最好的方法就是你所做的:Error? 其中nil 表示成功。它非常清晰和简单。

也就是说,另一个答案(也是我使用过的一个)正是在您的问题中:“如何使用 Result 处理 Void 成功案例。”成功案例通过Void,所以通过Void

Result<Void, Error>

“Void”并不意味着“不返回任何东西”。它是 Swift 中的一种类型,只有一个值:空元组 ()。这也恰好是类型:

public typealias Void = ()

按照惯例,我们使用Void 表示类型,使用() 表示值。在Result 中以这种方式使用Void 有点奇怪的是语法。你最终会得到类似的东西:

return .success(())

双括号有点难看,有点混乱。因此,即使这与其他使用Result 的代码很好地平行,在这种情况下我通常只使用Error?。不过,如果我有很多,我会考虑为它创建一个新类型:

enum VoidResult {
    case .success
    case .failure(Error)
}

【讨论】:

  • VoidResult 是个很优雅的名字=)
【解决方案2】:

我发现 Rob 的回答非常有趣和聪明。我只想提供一个可行的解决方案来帮助他人:

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

【讨论】:

    【解决方案3】:

    试试这个

    请注意,这是您可以根据测试更改的示例

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

    【讨论】:

    • 感谢您的回答,但我正在寻找带有 Result 的解决方案,以尽可能保持成功/失败语义
    • 我认为这是跟踪结果和闭包错误的更好方法。
    • 不过,我不明白这是如何工作的。您无法评估 !error,因为 error 不是 Bool
    • 是的,这是拼写错误
    • 这仍然没有意义。 Error 不是可选的。不能为零。要跳到下一步,我假设您的意思是 (AnyObject?, Error?),但这是一个糟糕的模式。它有4个案例,其中两个是非法的。如果通过(nil, nil),你的代码应该做什么? Result 的全部意义在于避免这种仅因为 ObjC 历史而存在于 Cocoa 中的模式。
    猜你喜欢
    • 2021-08-07
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-21
    相关资源
    最近更新 更多