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对象。 然后它将重复打印此人的name
和city
如John Appleseed
和Ohio
。 由于没有名为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
分配给protocols
, structs
, enums
甚至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
。 在第一种情况下,查找将找到FoodItem
与TaxAmount
的一致性。 在第二种情况下, Int
与TaxAmount
没有一致性,因此条件一致性失败。
本文由YellowJersey的iOS开发人员之一Ananth Bhamidipati撰写。 您也可以在Instagram上找到我们。