Swift 4.2有什么新功能?


Swift 4.2的第二个更新版本于2018年推出,Swift 4.2对该语言进行了一些重大改进。 阅读这篇文章,以了解它们如何帮助您编写更好的代码。

包含在此版本的改进列表中:

  • SE-0194 :添加CaseIterable协议以自动生成所有可能的枚举案例的数组。
  • SE-0195 :动态成员查找语法糖。
  • SE-0196 :新的编译器指令#warning#error
  • SE-0197 :新的removeAll(where:)方法可为集合执行优化的就地过滤器。
  • SE-0199 :新的toggle()方法可轻松切换/翻转布尔值。
  • SE-0202 :新的本机随机数生成器。
  • SE-0206 :新的Hasher类型,用于改进和简化对Hashable协议的一致性。
  • SE-0207 :新的allSatisfy()方法可验证序列中的所有元素是否通过条件。
  • SE-0143 :改善条件一致性。

枚举大小写迭代

首先,Swift 4.2引入了用于枚举的新协议。 如果使枚举符合CaseIterable协议,则可以以类似数组的方式遍历枚举列表,列出所有可能的情况。 例如,采用以下枚举:

enum ShirtSizeOptions: CaseIterable {
    case small, medium, large, extra-large
}

您可以使用新的allCases属性像迭代一样遍历此枚举列表,如下所示:

for size in ShirtSizeOptions.allCases{
    print("Shirt size is \(size)")
}

动态成员查找

添加了新属性@dynamicMemberLookup ,以允许Swift编译器在访问属性时利用下标方法,以便您可以为任意名称提供点语法,然后在运行时解析它们。 这从Python的约定中脱颖而出。 定义下标时,您将传递dynamicMember以及将返回的属性列表,如下所示:

@dynamicMemberLookup
class Shirt {
    subscript(dynamicMember member: String) -> String {
        let values = ["size": "small", "color": "Light Blue", "type": "kids"]
        return values[member, default: ""]
    }
}

此示例说明了如何在字符串中查找动态成员并返回一个字符串,同时在字典中查找该成员的名称。 以下实现说明了它是如何工作的:

let shirt = Shirt()

print(shirt.size) //small

print(shirt.color) //Light Blue

print(shirt.gender) //

实例化该类时,前两个属性是动态可发现的,并且将在运行时以类型安全的String返回成员的默认值。 最后一个属性( gender )在类中不存在,并且不会返回任何内容,因为在查找返回值时,我们使用空字符串作为默认值。 您不限于返回字符串-实际上,您可以从动态成员查找(包括闭包)中返回任何内容。

新的编译器警告和错误指令

这项新功能对于拥有Objective-C背景的许多人来说是过去的爆炸,因为该联盟为Swift引入(或重新引入了)编译器指令以标记代码中的问题。 这两个指令是#warning#error

#warning指令可帮助开发人员标记有问题的代码块,因此这些问题将在Xcode中显示为警告。 该#error指令,但是,将强制编译时错误,如果,例如,你想迫使开发人员看你的代码和完成的代码块,例如,是非常有用的,加入自己的API令牌或凭证代替占位符。 以下示例说明了后者的用例:

class APIServiceManager {
    #error("Please enter your own personal cloud token below")
    var cloudToken: String  = ""
}

对集合执行就地过滤的新方法

通过新的removeAll(where:)方法,开发人员现在可以通过传递闭合条件来对集合执行就地过滤。 假设您有一系列衬衫,并且想要删除特定的值medium 。 您之前可能已经做过类似的事情:

let shirtSizes = [“small”, “medium”, “large”, “extra-large”]

let mediumShirtRemoved = shirtSizes.filter { !$0.contains(“medium”) }
print(mediumShirtRemoved) // [“small“, “large“. “extra-large“]

通过添加removeAll(where:) ,您可以运行更多内存优化操作来显式地就地删除:

var shirtSizes = ["small", "medium", "large", "extra-large"]

shirtSizes.removeAll { $0.contains("medium") }
print(shirtSizes) //["small", "large", "extra-large"]

轻松在布尔值之间切换或翻转

SE-0199是一个简单但值得欢迎的改进,它通过toggle()方法引入了布尔切换。 以一种熟悉的模式,您将具有如下所示的内容:

var isShirtLarge = true
print(isShirtLarge) //true

isShirtLarge = !isShirtLarge
print(isShirtLarge) //false

通过添加此新方法,您可以编写:

var isShirtLarge = true
print(isShirtLarge) //true

isShirtLarge.toggle()
print(isShirtLarge) //false

新的本机随机数生成器

令人惊讶的是,在Swift 4.1之前,该语言缺少本机随机数生成器,从而迫使开发人员改为依赖arc4random_uniform()返回均匀分布的随机数。 现在,您只需调用random()方法以及特定范围即可使用:

var shirtSizes = [“small”, “medium”, “large”, “extra-large”]

let randomShirt = Int.random(in: 0 ..< shirtSizes.count-1)
print(shirtSizes[randomShirt]) //medium

Int以外的其他数字类型(包括FloatDoubleCGFloatBoolArray都支持此方法。

Bool使您可以返回随机的truefalse响应。 该建议还要求使用两个与数组相关的方法: shuffled()方法(用于随机化数组顺序)和randomElement() (用于从数组中返回随机元素)。

以下是如何使用新的shuffled()方法的示例:

var shirtSizes = [“small”, “medium”, “large”, “extra-large”]

let newShirtSizesOrder = shirtSizes.shuffled()
print(newShirtSizesOrder) //[“large”, “medium”, “extra-large”, “small”]

我们还可以使用randomElement()方法来改进我们之前获得随机衬衫大小的代码:

var shirtSizes = ["small", "medium", "large", "extra-large"]

//let randomShirt = Int.random(in: 0 ..< shirtSizes.count-1)
//print(shirtSizes[randomShirt])

print(shirtSizes.randomElement()) //extra-large

哈希协议一致性的改进

Swift通过新的Hasher结构改进了自定义对象类型符合Hashable协议的方式-使其变得更快,更简单,更安全。 以前,无论何时创建字典或集合,都将具有符合Hashable的类型,从而为您免费提供优化的哈希。 但是,当实现自己的符合Hashable的类型时,您需要创建自己的算法来手动计算hashValue

Swift 4.1通过推断可用于唯一标识对象的内容,显着改善了此问题:

class Shirt: Hashable {
    var size: String
    var color: ColorEnum
}

但是,当您必须使用更复杂的对象类型时,仍然需要实现一种算法以返回唯一的hashValue

Swift 4.2引入了新的Hasher结构,可以为您计算唯一的哈希值:

struct Shirt: Hashable {
    static func == (lhs: Shirt, rhs: Shirt) -> Bool {
        return lhs.size == rhs.size
    }
    
    var size: Int?
    var id: Int?
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(size)
        hasher.combine(id)
    }
}

要实现新的Hasher结构,请创建一个Hasher实例并提供要组合的自定义类型。 Hasher实例将创建并返回唯一的哈希。

确保序列中的所有元素都满足条件

Swift 4.2接受的最后一个功能是SE-0207 ,它添加了一个新方法allSatisfy() ,以验证序列中的所有项目是否符合特定的序列条件。 尽管您已经可以使用contains方法来验证集合中的某个元素是否满足条件,但是allSatisfy方法根据整个元素集是否满足条件来返回一个布尔值。

allSatisfy的以下实现声明是否超过$ 20的条件满足shirtOrderPrices的整个顺序:

var shirtOrderPrices = [42.99, 42.99, 23.90, 42.99, 32.99]
let weHaveMedium = shirtOrderPrices.allSatisfy { $0 > 20 } //true

结论

Swift仍然是一门不断增长的语言,不断增加新功能并进行辩论。 您可以通过访问Swift Evolution跟踪最新的提案列表以及每个提案的接受状态。

翻译自: https://code.tutsplus.com/tutorials/whats-new-in-swift-42--cms-32129

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值