swift 复选框纯代码_Swift可选。 使用还是不使用? 清洁我们的代码。

swift 复选框纯代码

The notion of Optional is a very powerful and convenient tool of modern Swift language. It allows us to write clean and readable code by eliminating checks for nil and providing functional programming tools. However, depending on the manner we use the tool, our code might be very clean or become very noisy.

Optional的概念是现代Swift语言的一种非常强大且便捷的工具。 通过消除对nil的检查并提供功能性的编程工具,它使我们能够编写干净且可读的代码。 但是,根据我们使用该工具的方式,我们的代码可能很干净或变得非常嘈杂。

可选的String作为变量(示例1)。 (Optional String as Variables (Example 1) .)

Let’s consider the next flow. We have the next model Album

让我们考虑下一个流程。 我们有下一个模特Album

We have a model Album that comes from the backend and as you can see description and copyright are optional strings. This is a normal practice for backend to return nil instead of empty attributes. It helps to save bytes in the payload and reduce traffic of a user.

我们有一个来自后端的Album模型,如您所见, descriptioncopyright是可选的字符串。 这是后端返回 nil 而不是空属性 的正常做法 它有助于节省有效负载中的字节并减少用户流量。

Imagine we have a simple task to add all 4 attributes to a UIStackView, and let’s say for the sake of the example we add a UILabel if a value exists. Here is the simple code we can come up with.

假设我们有一个简单的任务将所有4个属性添加到UIStackView,并且假设在该示例中,如果存在值,则添加UILabel 。 这是我们可以想到的简单代码。

Seems ok, but wait… With this approach if a copyright is empty, we will see a UILabel with the next string inside it: “Copyright:”. So let’s fix it.

似乎还可以,但是请稍候...使用这种方法,如果copyright为空,我们将看到一个UILabel其中带有下一个字符串:“ Copyright:”。 因此,让我们对其进行修复。

As you can see, we perform two checks: if the description is not nil and not empty. Basically let description: String? gives us 3 possible flows: isNil, notNilButEmpty, notNilNotEmpty. If this object is used several times in different places then there are chances for those checks to appear multiple times. Using String? later on in our business logic or UI logic, basically creates a lot of boilerplate code by forcing every level to do the same checks over and over again.

如您所见,我们执行两项检查:描述是否为nil且不为empty 。 基本上let description: String? 给我们3种可能的流程: isNilnotNilButEmptynotNilNotEmpty 。 如果在不同的地方多次使用此对象,则这些检查有可能多次出现。 使用String? 稍后,在我们的业务逻辑或UI逻辑中,基本上是通过强制每个级别反复进行相同的检查来创建大量样板代码。

This is a small and simple example why Optional variables could lead to a noisy code base.

这是一个小而简单的示例,为什么可选变量可能导致嘈杂的代码库。

In my practice I try to avoid String? where it doesn’t make sense or will create more work for me on the client side of the API.

在我的实践中,我尽量避免使用String? 在没有意义的地方,或者会在API客户端上为我创建更多工作。

可选作为变量(示例2)。 (Optionals as Variables (Example 2) .)

Optional Variables in ViewControllers is another pattern that could lead to noisy code. Consider we have a BaseUserViewController that contains info about a User as Optional and provide method to create a greeting

ViewControllers中的可选变量是另一种可能导致嘈杂代码的模式。 考虑我们有一个BaseUserViewController ,其中包含有关User信息(可选),并提供创建问候语的方法

Easy task, we create our controller, connect segue in StoryBoard and add the code in Presenting controller:

轻松完成任务,我们创建控制器,在StoryBoard中连接segue,然后在Presenting controller中添加代码:

Note: I’m deliberately using segue approach as an example, since this is one of the reasons why people use optionals for passing data between ViewControllers

注意:我故意使用segue方法作为示例,因为这是人们使用可选方法在ViewController之间传递数据的原因之一。

Everything is OK and seems nothing wrong with that. Now we need to have another view controller with different UI layout that uses User object and also need a method to create a greeting. The basic and straightforward approach is to subclass BaseUserViewController

一切都很好,似乎没有错。 现在,我们需要另一个使用User对象的具有不同UI布局的视图控制器,还需要一种创建问候语的方法。 基本而直接的方法是BaseUserViewController

In this pseudo code we can see that in new function savePlaylistForCurrentUser we have to use optional binding to unwrap the value and continue the flow. My point here is that for any new function that need to deal with UserModel?, we have to use an optional binding pattern, thus polluting our code base for no reason.

在此伪代码中,我们可以看到在新函数savePlaylistForCurrentUser我们必须使用可选绑定来解开值并继续执行流程。 我的意思是,对于需要处理UserModel?任何新功能UserModel? ,我们必须使用可选的绑定模式,从而无故污染我们的代码库。

My solution for this is using dependency injection and trying to avoid storing Optional values for any dependency.

我对此的解决方案是使用依赖项注入,并尝试避免为任何依赖项存储Optional值。

可选作为函数参数。 (Optionals as Function Arguments .)

Another thing that I’ve seen a lot is passing Optional argument into a function. This is also a pattern that could lead to more work for ourselves and messier code base. If we pass optional into a function that already means that the function will have more than two reasons to change(Single Responsibility Principle). Consider the next function:

我见过很多的另一件事是将Optional参数传递给函数。 这也是一种模式,可能导致我们自己和更混乱的代码库投入更多工作。 如果我们将可选传递给函数,则已经意味着该函数将具有两个以上的更改原因(单一职责原则)。 考虑下一个功能:

We pass the user as an Optional value here. I understand the intent and usually that’s because it’s easy for us. As for example about view controller above, it’s easy to create such function. However does it make sense? We continue create more work for ourselves by propagating optionals everywhere and forcing unnecessary checks on every level.

我们在此处将用户作为可选值传递。 我了解目的,通常是因为这对我们来说很容易。 以上面的视图控制器为例,创建此类功能很容易。 但是,这有意义吗? 我们通过在各处传播可选内容并在每个级别上强制进行不必要的检查来继续为自己创造更多的工作。

The solution here is to try to avoid passing optionals into functions unless it’s really necessary.

此处的解决方案是尝试避免将可选参数传递到函数中,除非确实有必要。

可选和数组。 (Optionals and Arrays.)

Another common “mean” of polluting the code and creating more work for ourselves is using Optional Arrays, Array of Optionals, Optional Array of Optionals

另一种常见的污染代码和创建自己给自己更多的工作“是指”使用可选的阵列选配的阵列选配的数组(可选)

In this example we use Optional array of tracks. The lines 5–7 doesn’t create us too much noise due to nil-coalescing operator.

在此示例中,我们使用可选的音轨数组。 第5-7行不会由于n-coalescing运算符而给我们带来太多噪音。

In the cellForRowAt method we have to use optional binding. If I read the code, I assume that the array might be nil and when it happens we return empty cell. Someone might say: “If you look above, Alex, this will never happen since we return number of items at lines 5–7. Technically, this case is almost impossible.” Then I have a question: if this is not supposed to happen, then why write it? Why use patterns that lead to unnecessary code? Why couldn’t we have just [Track] and avoid noise? Yes, instead of using guard we could use if let and put setting up a cell with the model inside the if scope. However the question remains the same.

cellForRowAt方法中,我们必须使用可选绑定。 如果我读了代码,我认为该数组可能为nil并且当它发生时,我们返回空单元格。 有人可能会说: “ Alex,如果您在上面看,这将永远不会发生,因为我们在第5-7行返回了项目数。 从技术上讲,这种情况几乎是不可能的。” 然后我有一个问题:如果不应该这样,那为什么要写呢? 为什么使用导致不必要代码的模式? 为什么我们不能只使用[Track]避免噪音? 是的,我们可以使用if let并使用if范围内的模型来设置单元格,而不是使用guard 。 但是,问题仍然相同。

Let’s look at the function we a cell is selected.

让我们看一下选择单元格的功能。

Again having optional value causes us to implement optional binding again. On top, when you access array by index, as a rule of thumb, it’s better to make sure that your index is not out of bounds. For example, if your dataSource(array in this case) is updated in the background thread there is a potential risk of a crash. So now the code above will be modified like.

再次具有可选值会使我们再次实现可选绑定。 最重要的是,根据经验,当您按索引访问数组时,最好确保索引不超出范围。 例如,如果您的dataSource(在这种情况下为array)在后台线程中更新,则存在崩溃的潜在风险。 所以现在上面的代码将被修改为。

Do you want me to show you more examples using [Track?] or [Track?]?. I hope you get my point.

您是否希望我使用[Track?][Track?]?向您展示更多示例[Track?]? 。 希望你明白我的意思。

可选词典。 (Optional Dictionaries.)

Using dictionaries as optionals has the same issues as [Track?]?. You need to deal with optional dictionary first and then with optional value. Having optional value in the dictionary is a normal thing, and it is easy to work with if you’re using functional approach on optionals

将字典用作可选内容与[Track?]?有相同的问题[Track?]? 。 您需要先处理可选字典,然后再处理可选值。 在字典中具有可选值是很正常的事情,如果对可选对象使用函数方法 ,则很容易使用

可选的返回值 (Optionals as returning value)

Returning optional values/optional values in callbacks is also a pattern that is abused a lot and leads to code smell in my option. Let’s scroll up and look at this function again:

在回调中返回可选值/可选值也是一种被滥用的模式,导致我选择的代码有气味。 让我们向上滚动并再次查看此功能:

It returns optional array. Now the question, I’m a client of this API. Why is it optional? Was it not found? Was the user missed? Was it an error during fetching? The point is, yes, sometimes we might need return value as an optional, since it’s not important for us or in some cases it does make sense to return optional value. However, the more I develop the more I lean toward throwing errors or using Swift Result that could be handled by a client properly. Maybe I’m becoming lazy when it comes debugging errors 🤷‍♂️?

它返回可选数组。 现在的问题是,我是该API的客户端。 为什么是可选的? 没有找到吗? 用户错过了吗? 撷取时发生错误吗? 关键是,是的,有时我们可能需要返回值作为可选值,因为这对我们而言并不重要,或者在某些情况下返回可选值确实有意义。 但是,我开发的越多,我越倾向于抛出错误或使用可由客户端正确处理的Swift Result。 也许我在调试错误时变得懒惰🤷‍♂️?

可选错误 (Optional Errors)

This is probably the most confusing pattern for me.

对我来说,这可能是最令人困惑的模式。

Here is Apple old-style API:

这是Apple旧式API:

Note: I’m aware where it comes from and why. However on high-level I’m trying to avoid this type of pattern

注意:我知道它的来源和原因。 但是在高级别上,我试图避免这种类型的模式

As you can see, there are 3 returned optional values. How many combinations do we have here?

如您所见,有3个返回的可选值。 我们在这里有几个组合?

  • We have Data and Response and Error == nil . This one might mean the request reached the server and we got a response. The status of the response will tell us if it was a success or not

    我们有DataResponseError == nil 。 这可能意味着请求已到达服务器,我们得到了响应。 响应的状态将告诉我们是否成功

  • We have Error, Data, Response. This should not happen theoretically, however according to API declaration is possible

    我们有ErrorDataResponse 。 从理论上讲这不应该发生,但是根据API声明是可能的

  • We have Error, Data == nil, Response == nil. Means the request didn’t reach the server.

    我们有ErrorData == nilResponse == nil 。 表示请求未到达服务器。

  • We have Response, Data == nil, Error == nil, We reached the server and got the response but the body is empty.

    我们有ResponseData == nilError == nil ,我们到达服务器并获得了响应,但主体为空。

  • All the returned params are nil. Also quite impossible, but according to API there is a possibility.

    返回的所有参数均为零。 同样是完全不可能的,但是根据API,这是有可能的。

I skipped the other cases, because I hope you got my point at this type. In some cases it’s inevitable to have API like that, specially if you work with or develop a low-level SDK. However propagating this pattern to the client higher level creates unnecessary checks whenever this pattern is used.

我跳过了其他情况,因为我希望您对这种类型的观点有所了解。 在某些情况下,拥有这样的API是不可避免的,特别是当您使用或开发低级SDK时。 但是,每当使用此模式时,将此模式传播到客户端更高级别都会创建不必要的检查。

As a solution I use Swift.Result to have a well defined states.

作为解决方案,我使用Swift.Result具有良好定义的状态。

结论: (Conclusion:)

Optionals is just a tool in swift language. As it happens if we use tools wisely we can have very good results, clean and less error-prone code. On the other side misusing of any tool can lead to more work, more debug, maybe more money and maybe less time to learn and grow as a specialist.

Optionals只是一种快速语言的工具。 碰巧如果我们明智地使用工具,我们将获得非常好的结果,干净的代码以及不易出错的代码。 另一方面,滥用任何工具都可能导致更多的工作,更多的调试,可能更多的金钱以及可能更少的时间学习和成长为专家。

翻译自: https://medium.com/swift-gurus/swift-optionals-to-use-or-not-to-use-cleaning-our-code-ea394db2c6a9

swift 复选框纯代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值