Swift-避免守卫/过度使用和可选配置的最佳实践

时间:2019-07-03 14:18:35

标签: swift

我发现我的代码中完全堆满了可选内容和警卫/警惕语句。

一个例子是,我有一个在几个VC中填充的对象,因此该对象中的变量是可选的。当我在函数中使用整个请求时,它会导致如下荒谬的事情:

func save(request: Request, completion: @escaping WebServiceResponse){
        guard let description = request.description,
            let totalAmount = request.totalAmount,
            let reserveAmount = request.reserveAmount,
            let holdingPeriod = request.holdingPeriod,
            let sender = request.sender,
            let receiver = request.receiver
            else {
                return
        }
        apiRequest(endpoint: apiEndpoint.Deal, path: "/save", body:
            [
                "description" : description,
                "total": totalAmount,
                "reserve": reserveAmount,
                "period":holdingPeriod,
                "from":sender,
                "to":receiver
            ], completion: completion)
    }

每当我使用可选对象时,尤其是在类对象中使用可选对象时,我都会在代码中发现这些问题。

One answer建议我增加进一步的复杂性,以检查是否已设置该方法...这会使我的代码更加不可读。有什么方法可以批量解开课程吗?还是可以尝试/捕捉?

我该如何改善?

2 个答案:

答案 0 :(得分:3)

这是一个“构建者”问题,它有一些解决方案。

一种方法是将可变结构与不可变结构分开。使用具有var可选值的可变RequestBuilder进行构建。然后,完成后,将其转换为具有let非可选值的不可变请求。这将迫使您一次做这个巨大的if-let,但是那样就可以了。

另一种方法是为所有值提供默认值。通常,集合(包括字符串)不应是可选的。只是将它们清空。

答案 1 :(得分:1)

Rob Napier的builder方法似乎非常好。这是另一个想法。

您可能在request上有一个函数,可以返回您需要传递给apiRequestnil的字典(如果未填写任何值)。 guard语句,但只放在一个地方:

extension Request 
{
    func makeDictionary() -> [String: String]?
    {
        guard let /* blah blah blah */ else { return nil }
        return [
                "description" : description,
                "total": totalAmount,
                "reserve": reserveAmount,
                "period":holdingPeriod,
                "from":sender,
                "to":receiver
            ]
    }
}

func save(request: Request, completion: @escaping WebServiceResponse){
        guard let body = request.makeDictionary() else { return }
        apiRequest(endpoint: apiEndpoint.Deal, path: "/save", body: body, completion: completion)
    }