Swift 4.2有什么新功能?

又是一年中的那个时候,用于新的Swift语言更新。 4.2是Swift 4系列中继4.0和4.1之后的第二次更新。 在此博客中,让我们检查Swift 4.2中的新增功能,并记住Swift 4.2需要Xcode 10,并确保在开始之前运行Xcode 10。

枚举案例的派生集合:

引入了新的CaseIterable协议,该协议默认情况下会生成枚举中所有案例的数组属性。 我们只需要遵循CaseIterable协议,编译器就会生成allCases属性,该属性是所有枚举案例的数组。

 枚举   CompassDirection:CaseIterable { 
案例北,南,东,西
}
print(“有\(CompassDirection.allCases.count)方向。”)
//打印“有4个方向。” let caseList = CompassDirection.allCases
.map({“ \($ 0)”})
.joined(分隔符:“,”)
// caseList ==“北,南,东,西”

allCases的自动综合仅适用于不使用关联值的enum 。 但是,如果需要,我们可以自己添加它们。

 列举城市:CaseIterable { 
静态var allCases:[城市] {
返回[.antwerp,.brussels,.mumbai,.hyderabad(国家名称:“印度”)]
}

安特卫普案例
布鲁塞尔
孟买
大小写hyderabad(countryName:String)
}

新的编译器指令:

Swift 4.2引入了#warning#error指令,它们会提示Swift编译器在编译期间发出自定义警告或错误

  • #warning主要用于提醒自己或其他人某些工作尚未完成。
  • 如果提供的库需要其他开发人员提供一些数据,则#error主要有用。

#warning#error工作方式相似。

  func crypto(_字符串:字符串,密码:字符串)->字符串{ 
#warning(“这是可怕的加密方法”)
返回密码+字符串(string.reversed())+密码
}结构配置{
var apiKey:字符串{
#error(“请在下面输入您的API密钥,然后将其删除”)
返回“在这里输入您的密钥”
}
}

#warning#error都可与现有的#if编译器指令一起使用,并且只有在所评估的条件为true时才会被触发。 例如:

  #如果为假 
#warning(“这不会触发警告”)
#error(“这不会触发错误”)
#endif#if true
#warning(“这将触发警告”)
#error(“这将触发错误”)
#万一

随机数生成:

在Swift 4.2中,新的随机API被添加到标准库中以生成一个随机数。 我们可以通过在我们选择的任何数字类型上调用random()方法来生成随机数。 random()方法也可以用于boolean类型。

以下是使用random()方法的一些示例”

  //生成一个介于1到100之间的随机数 
让randomInt = Int.random(in:1 .. <100)
让randomFloat = Float.random(in:1 .. <100)
让randomDouble = Double.random(in:1 ... 100)
让randomCGFloat = CGFloat.random(in:1 ... 100)//生成一个随机布尔值
让randomBoolean = Bool.random()

除了random()方法之外,还添加了新的randomElement() ,它从数组返回一个随机元素。

  var groceryList = [“牛奶”,“鸡蛋”,“面包”,“ Nutella”]如果让randomGroceryItem = groceryList.randomElement(){ 
print(“杂货店的随机物品是\(randomGroceryItem)”)
}
//随机的杂货项目是牛奶

Swift 4.2提供了更有效的改组算法。 我们可以简单地使用shuffle()方法对数组的元素进行随机重排序,并使用shuffled()方法来返回已排序的序列元素。

 变量名称= [“ Alejandro”,“ Camila”,“ Diego”,“ Luciana”,“ Luis”,“Sofía”] 
names.shuffle()
// 名称== [“ Luis”,“ Camila”,“ Luciana”,“Sofía”,“ Alejandro”,“ Diego”]数字= 0 ... 9
让shuffledNumbers =数字.shuffled()
// shuffledNumbers == [1、7、6、2、8、9、4、3、5、0]

测试序列元素:

Swift 4.1缺乏一种简单的方法来检查序列中的所有元素是否都满足特定条件。 Swift 4.2通过添加新的allSatisfy(_:)方法进行了介绍。 这简化了代码,并提高了可读性。

 让名字= [“索非亚”,“卡米拉”,“马丁娜”,“马托”,“尼古拉斯”] 
让allHaveAtLeastFive = names.allSatisfy({$ 0.count> = 5})
// allHaveAtLeastFive == true

从集合中删除元素:

Swift 4.2中引入了removeAll(where:)方法,以删除满足特定条件的集合中的每个元素。 现在,我们不再需要使用filter方法。

 变数= [5、6、7、8、9、10、11] 
number.removeAll(其中:{$ 0%2 == 1})
//数字== [6、8、10]

布尔切换:

bool中引入了新的toggle()方法,该方法有助于在true和false之间toggle() 。 尽管它看起来似乎不是一个很大的补充,但它使Swift易于编写,许多开发人员可能会发现这很有趣。 在复杂的数据结构中特别有用。

  var bools = [true,false] 
bools [0] .toggle()// bools == [false,false]

动态成员查找:

Swift 4.2中,引入了@dynamicMemberLookup属性。 使用它的类型为在运行时解析的任意名称提供“点”语法-以完全类型安全的方式。

  @dynamicMemberLookup 
struct Person {
下标(dynamicMember参数:字符串)->字符串{
let properties = [“ personName”:“ John Appleseed”,“ City”:“俄亥俄州”]
返回属性[参数,默认值:“”]
}
}让person = Person()
打印(person.name)
打印(person.city)
打印(人)
// John Appleseed
//俄亥俄州
//

在上面的示例中,按原样创建了Person对象。 然后它将重复打印此人的namecityJohn AppleseedOhio 。 由于没有名为age属性,它将返回一个空字符串。 subscript(dynamicMember:)方法必须返回一个字符串,这是Swift的类型安全性所在的地方。即使您正在处理动态数据,Swift仍将确保您获得期望的结果。

我们可以为不同的数据类型实现不同的subscript ( dynamicMember:)方法。

  @dynamicMemberLookup 
struct学生{
下标(dynamicMember成员:字符串)->字符串{
let properties = [“名称”:“约翰·Appleseed”,“城市”:“纳什维尔”]
返回属性[成员,默认值:“”]
}下标(dynamicMember成员:字符串)-> Int {
let properties = [“ age”:25,“ height”:169]
返回属性[成员,默认值:0]
}
}
让学生=学生()
年龄:整数=学生年龄

我们还可以重载下标以返回闭包:

  @dynamicMemberLookup 
struct用户{
下标(dynamicMember成员:字符串)->(_输入:字符串)->无效{
返回{
print(“你好!我住在地址\($ 0)。”)
}
}
}让用户= User()
user.print(“公园街大街687号”)
//你好! 我住在公园街大街687号。

如果在具有某些常规属性和方法的类型中使用动态成员下标,则将始终使用这些属性和方法代替动态成员。 例如,我们可以使用内置成员name属性和动态成员下标定义Singer结构:

  struct Player { 
public var name =“ Eden Hazard”下标(dynamicMember成员:String)-> String {
返回“ Romelu Lukaku”
}
}让玩家=玩家()
打印(player.name)
//伊甸园危害

该代码将打印“ Justin Bieber”,因为将使用name属性而不是动态成员下标。

可以将@dynamicMemberLookup分配给protocolsstructsenums甚至classes

条件符合性:

Swift 4.2对扩展和标准库引入了一些条件一致性改进。 Swift,现在允许我们在运行时查询条件一致性。 因此,可以检查我们接收到的数据是否可以转换为符合条件的协议。

 协议TaxAmount { 
func taxAmount()
}

上面,我们有一个TaxAmount protocol

  struct FoodItem:TaxAmount { 
var rate = 1000.0func taxAmount(){
出租税=利率/1.25
打印(含税)
}
}

以及符合TaxAmount协议的简单struct

  extension Array:Messages where元素:Messages { 
func taxAmount(){
forEach {$ 0.taxAmount()}
}
}

我们只要使用Element ,就可以where约束Array以符合TaxAmount

  func computeTax( _ value:Any){ 
如果让p =值为as? 税额 {
p.taxAmount()
}其他{
打印(“非应税对象”)
}
} calculateTax([FoodItem(),FoodItem(),FoodItem()])
// 800
// 800
// 800calculateTax([1、2、3])
// “不是应税对象”

TaxAmount calculateTax(_:)if-let动态查询value的类型是否符合协议TaxAmount 。 如果是Array ,则该一致性是有条件的,并且需要另一次动态查找以确定该元素类型是否符合TaxAmount 。 在第一种情况下,查找将找到FoodItemTaxAmount的一致性。 在第二种情况下, IntTaxAmount没有一致性,因此条件一致性失败。


本文由YellowJersey的iOS开发人员之一Ananth Bhamidipati撰写。 您也可以在Instagram上找到我们