优雅的雨燕

让我解释一下:我写了很多Swift。

在工作中,我编写了Swift(以及一些Objective-C,但我不想谈论它)。 在我的大多数附带项目中,我都编写Swift。 每当我需要快速脚本时,我都用Swift编写它。

免责声明

一些代码片段使用非常规符号或不寻常的语法。 自行决定使用。 与可能不熟悉这种语法的队友共享代码可能会有所帮助。

声明自定义运算符

运营商是万恶之源,必须不惜一切代价避免。 这是在Scala或C ++中使用运算符繁重库的任何人的传统智慧。

但是我认为有一类运营商在世界上占有一席之地。 确实,处理通用类型且没有歧义的运算符,或者比典型的Swift语法更清楚地表达意图的运算符具有实际价值。 它们使用户可以理解代码的作用,而不是如何操纵语法以使代码工作。

例如,我认为:

  A + B * C ^ D 

 加(A,次(B,功率(C,D))) 

此外,由于许多语言都有某种中缀和前缀运算符语法,因此运算符与语言无关,有助于熟悉。

这是我在个人项目中经常定义的几个运算符。

求反运算符

如果您熟悉DeMorgan法律,您可能会看到它像这样写

好吧事实证明了这一点

  ¬(a && b)==¬a ||  ¬b 

是有效的Swift语法(并且将始终为true)。

Swift自定义运算符允许使用这种可爱的语法,这是声明

当然,“!”的简写方式只有在数学上比较倾向于的情况下才有意义。

您可以在macOS上使用alt-L在美国键盘布局上打“¬”符号。

合成运算符

您听说过无点符号吗? 当您执行此操作时:

 令h = f•g 

相当于这个

 设h = {x in f(g(x))} 

或这个

 令h = {f(g($ 0))} 

但是这些表达都不是特别令人愉快的阅读。 在这两种情况下,我们都引入了不必要的括号,并且必须破译嵌套的括号。

当然,无点符号在其语法中并非没有“点”,但没有声明带有多余参数名称的中间闭包。

无点符号在Swift中非常罕见,因为在标准库中不是运算符,但是当您开始使用它时,很难停止。 例如:

 让saveOnDisk =存储•序列化 

清楚地表明,将数据保存在磁盘上的功能以一种可表示的方式将数据序列化以用于数据存储,然后将结果存储在磁盘上。

如果我们写下类型,我们有

  func serialize(data:Data)-> JSON {…} 
func store(json:JSON)->(){…}
让saveOnDisk:(JSON)->()=存储•序列化

您还可以在测试中使用无点符号:

  func testSerialize(){ 
让数据=…
let doNothing =反序列化•序列化
XCTAssert(data,doNothing(data))
}

测试什么都不是实际上是一个身份函数。

您可以使用美国布局在macOS上键入alt-8来在键盘上找到“•”运算符。

至于实现,这里是一个,但是我建议您导入Swiftz或Swiftx。

部分应用运算符

当您写很多东西时,您会开始看到模式的出现。 这是一个:

您有一个应用程序,其中列出了给定客户的所有订单。 订单以其状态表示

 枚举CustomerOrder { 
装运箱(国际)
案件等待付款
}

假设您有一个orders: [CustomerOrder]列表orders: [CustomerOrder]您想要所有需要付款的订单。 当然,您可以这样写:

  orders.filter {$ 0 == .awaitingPayment} 

但过了一会儿,您开始质疑为什么还要输入这些括号和$0参数。 原来这是有效的

  orders.filter(==。awaitingPayment) 

它使用==作为前缀运算符

您也可以使用比较运算符执行相同操作。 不幸的是,某些运算符不能被覆盖(后缀>和前缀< ),因此我们只能使用<? 以及类似的解决方法。

 让年龄:[Int] = users.map {$ 0.age} 
让allCanDrink = ages.forAll(suchThat:?> 21)
 让allAreBabies = ages.forAll(suchThat:?<4) 

你可以用后缀参数做同样的事情

 让wontEnjoyRetiring = ages.forAll(suchThat:40>?) 

这是详细的实现:

https://gist.github.com/andrevidela/45c734248a3cb0a0507123c89df08699

数组扩展

您可能已经注意到,标准库中不存在forAll(suchThat:)方法。 但是由于有了extensions我们可以轻松地为数组定义它:

 扩展数组{ 
func forAll(suchThat谓词:(Element)-> Bool)-> Bool {
return¬self.contains(其中:{¬predicate($ 0)})
}
}

还有很多!

我们都定期定义和使用许多其他辅助函数,扩展和类型。 如果您向我发送电子邮件或发送带有您最喜欢的自定义声明的推文,我将不胜感激,该声明可以帮助您减少样板并清楚地表达您的意图。