我发现我的代码中完全堆满了可选内容和警卫/警惕语句。
一个例子是,我有一个在几个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建议我增加进一步的复杂性,以检查是否已设置该方法...这会使我的代码更加不可读。有什么方法可以批量解开课程吗?还是可以尝试/捕捉?
我该如何改善?
答案 0 :(得分:3)
这是一个“构建者”问题,它有一些解决方案。
一种方法是将可变结构与不可变结构分开。使用具有var
可选值的可变RequestBuilder进行构建。然后,完成后,将其转换为具有let
非可选值的不可变请求。这将迫使您一次做这个巨大的if-let
,但是那样就可以了。
另一种方法是为所有值提供默认值。通常,集合(包括字符串)不应是可选的。只是将它们清空。
答案 1 :(得分:1)
Rob Napier的builder方法似乎非常好。这是另一个想法。
您可能在request
上有一个函数,可以返回您需要传递给apiRequest
或nil
的字典(如果未填写任何值)。 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)
}