Tag: 运营商

条件赋值运算符

开发人员通常需要根据可选值构建字典。 当然,在Swift中很容易做到,对吧? 只是[String:Any?],所以为什么写一篇有关它的博客文章? 对于便利的条件赋值运算符,我们将其用作用例之一。 因此,让我们来看一个现实生活项目中的示例-Zonky。 该应用程序显示一个屏幕,您可以在其中选择多个贷款参数以过滤贷款列表。 当然,所有这些参数都是可选的。 为了应用选定的过滤器,我们需要将参数作为字典发送到服务器。 带有字典的过滤功能如下所示: 看来还可以,但是我们不希望字典中出现可选内容,因为Alamofire将[String:Any]作为参数字典的一种类型。 我们该如何解决? 最直接的解决方案非常明显: 很好,它可以工作,但是请想象更大的参数集。 那是很多丑陋而无聊的代码! 👎这就是导致我们了解条件赋值运算符背后的思想的原因。 我们只想为字典分配一个值,除非它不是nil。 Voilà。 更短,更美观,更易读💪但它不是Swift附带的标准运算符,因此让我们看一下它的幕后工作方式。 基本思想很简单-我们只是将第二个示例中使用的展开代码和赋值代码移到了自定义运算符定义中。 就是这样! 我们有一小段代码,这使我们的代码库变得更好。 您不仅可以使用此运算符来构建字典(还有其他甚至可能更聪明的方法来实现此目的),而且只要需要仅在值不为零时才赋值,并且相信我,这是一个很常见的情况,您会喜欢😏 如果您喜欢这个简单的技巧,请参阅我们的ACKategories-轻量级的开放源代码库,其中包含类似的有用工具和扩展,或者仅等待我们的下一篇博客文章,我们将为您展示更多来自厨房的食谱👨‍🍳 … 最初于 2018 年6月4日 发布在 www.ackee.cz 上。

通过Nil-Or-Empty-Coalescing运算符(???)为空或不存在的可选项提供有意义的默认值

要解决此问题,我必须先打开可选包装,并检查它是否为nil或为空。 在这种情况下,我提供了一些有意义的默认值,例如,让用户知道他要查找的值当前不可用。 过去不久,我偶然发现了?? 运算符(顺便称为Nil合并运算符),它使您可以为nil的可选选项提供默认值。 但这不能解决可选不是null而是空的情况。 由于我不喜欢一遍又一遍地写相同的代码,只是稍微改变一下语法以反映变量名,所以我发现必须有一个更好的方法。 幸运的是,我们可以轻松扩展Optional并实现一个不错的功能来为我们做这件事。 我们只需要在扩展中编写一次解开代码,就不必再碰它了。 如果由于某种原因必须更改它,我们可以方便地在一个地方更改它,而不必经历整个项目,这确实很痛苦。 所以这里是: 那更好。 一个简单的函数,检查该值是nil还是空,并在这种情况下使用默认值。 但是,为什么我们要限制自己使用String? 使它成为各种可选功能的通用功能不是很好吗? 我认为是的,这就是为什么我更进一步。 当然,并非每个可选项都具有isEmpty属性。 字符串和数组都有它们,但是一个空的Int会是什么样子? 多数民众赞成在一个简单的解决。 我们可以使用isEmpty属性创建一个协议。 然后,我们可以限制我们的功能以查找实现上述协议的Optional。 如您所见,对于String和Array,我们甚至不需要实现某些东西,因为这些类型已经具有isEmpty属性。 现在,让我们以默认情况下没有isEmpty属性的类型实现我们的新成就,以查看它是否确实像我们期望的那样运行(我的意思是,无论如何,谁会信任计算机?) 哇,真棒。 真的行。 但是如果你像我一样,那你就是懒惰。 甚至可能是如此懒惰,以至于即使使用自动完成功能,键入“ orWhenNilOrEmpty”也已经非常费力。 当我意识到自己多么懒惰时,我想起了? 操作员。 您是否知道在Swift中可以编写自己的运算符? 当我在上面的代码上工作时,我偶然发现了这一点,这完全让我震惊。 对我来说,这是那些绝对幸运的事故之一,使我自己怀疑是否有巧合之类的事情。 这只是为了完美。 我必须立即尝试一下,这是我想到的: 我称它为“无或空”促销员,我很喜欢它。 我希望这一小部分内容可以帮助您编写更好的代码。 对我来说,这是一次很棒的学习经历。 在改进对Optional的理解的方式上(之前我从未关心过.some(wrapped)和.none,我实际上也不了解它们),我改善了对协议扩展和约束的了解,最后但并非最不重要的一点是,了解了如何编写自定义运算符。 我的建议是,每当发现自己编写相同或非常相似的代码两次以上时,就一定要研究是否存在更好的方法。

iOS:RxSwift +干净的架构

在上一篇文章中,我们有机会从概念上定义应用程序的体系结构。 这篇文章的目的是深入了解我们正在使用的该体系结构的关键组件的实现。 在这篇文章中,我们将讨论如何实现: RxSwift +干净的架构 我们的应用程序使用ReactiveX swift版本:RxSwift。 RxSwift是组合异步操作和事件/数据流的强大工具。 这些流使层之间的通信变得容易。 这就是为什么我们认为它完全适合我们的架构需求。 该方案表示RxSwift流经体系结构不同层的方式: 基本上,Presenter执行返回一个Observable的用例。 此Observable在数据层上创建,并由域层传递。 演示者订阅此Observable来从存储库中获取结果。 但是,什么是可观察的? 如果我们阅读RxSwift的入门文档,我们可以理解什么是Observable: 每个Observable序列只是一个序列。 Observable vs Swift的Sequence的主要优点是它还可以异步接收元素。 这是RxSwift的内核。 让我们逐层介绍实现: 实作 UI层 演示者有一个要执行的用例。 方法execute返回一个Observable。 演示者订阅了此Observable: 请注意,在订阅关闭之后,我们将调用disposed(by: disposeBag) 。 此方法将订阅添加到disposeBag中以取消该订阅。 最后,在闭包内部使用[unowned self]或[weak self]并使用dispose(by:)方法可以避免内存泄漏。 😉 域层 用例具有一个execute方法,该方法调用CatalogRepository协议方法并返回由该存储库创建的Observable: 资料层 数据存储库实现在域层中定义的CatalogRepository协议,并具有数据源和数组。 这些数据源又实现了CatalogDataSource协议。 在数据存储库的每个方法内部,它为包含的每个数据源从CatalogDataSource调用一个函数。 为了连接这些调用,我们使用Observable的操作concat ,如下所示: 远程数据源创建一个Observable并使用Alamofire执行请求。 响应结果将通过Observable onNext() , onCompleted()或onError()方法发送给演示者。 就这样! 通过层连接完成! ✅ 这可能是每个人的应用程序中的常见情况,但是RxSwift是一个功能强大的工具,这只是冰山一角。 让我们深入了解我们在项目中使用更多的东西之一: 经营者 RxSwift中有许多运算符:创建,转换,过滤,合并……可以使您的生活更轻松。 […]

操作员超载

运算符重载是Swift编程语言的强大功能之一。 从本质上讲,它基本上是对任何您想要的类型使用-,+,==,/,*运算符。 另外,您可以定义自己的运算符,并在项目中使用它们。 多么酷啊? 假设您有一个新闻项目,并且正在处理一些文章: 结构文章{ 变量ID = 0 var title =“” var desc =“” init(id:Int,title:String,desc:String){ self.id = id self.title =标题 self.desc =说明 } } 让articleA = Article(id:1,标题:“ Title#1”,desc:“ Article description#1”) 让articleB = Article(id:2,标题:“ Title#2”,desc:“ Article description#2”) 让articleC = Article(id:2,标题:“ Title#2”,desc:“ Article description#3”) 现在,我们需要检查两个文章是否相同,但是逻辑是,只有id和title相同时,它们才是相同的。 可能,我们将使用if语句以老式的方式进行操作。 如果articleB.id == articleC.id && articleB.title == articleC.title { 打印(“文章相同”) }其他{ […]

操作员trong swift iOS

快速操作员swiftcócácloạinhư: 一元 :cáctoántửdùngcho 1đốitượng 一个= ! b //前缀 a = b为! c //后缀 二进制 :cáctoántửdùngcho 2đốitượng a = b * c //中缀 三元 :cáctoántửdùngcho 3đốitượng,vàchỉcó1làdùngchotrườnghợpkiểmtrađiềukiệnthaythế a> 0? : 操作员超载 struct Vector2D :ExpressibleByArrayLiteral { var x = 0.0,y = 0.0 init(x:Double,y:Double){ self.x = x self.y = y } init(arrayLiteral:Double …){ self.x = arrayLiteral [0] self.y = […]