美文网首页iOS 项目上线经验ios开源项目ios
SwiftUI内功之Swift5.2 给我们带来了什么新惊喜

SwiftUI内功之Swift5.2 给我们带来了什么新惊喜

作者: iCloudEnd | 来源:发表于2020-04-24 23:42 被阅读0次

    Swift 5.2 现已作为 Xcode 11.4 的一部分公开发布。本文中将带来着大家体验一下Swift 5.2 的新特性。看看给我们带来了什么新的惊喜。

    总体而言,Swift 5.2 是一个小版本,它确实带来了许多调整和微小的改进。在此版本中,您将找到:

    • 更好的诊断与更有用的错误消息,特别是对于 SwiftUI。
    • 可简化某些任务的新功能。
    • 主要错误修复。

    改进的诊断和错误消息

    您总是在第一次尝试时就编写完美的代码吗?如果没有,您会喜欢Swift 5.2中诊断引擎的改进!当您的代码中有错误时,编译器会为您提供有关错误及其位置的更准确的描述。

    公平地说,Swift编译器已经很好地报告了代码中的大多数错误。下面的代码:

    var str = "10"
    let total = str + 5
    
    
    image.png

    错误消息告诉您,您不能使用“ +”运算符来连接字符串和整数。根据您的意图,它还会指出您要采取的解决问题的措施。如果目标是在字符串表示的数字上加5,则可以像这样修复错误:

    var str = "10"
    let total = Double(str)! + 5
    
    

    在其他时候,错误消息并没有那么大的帮助。对于与类型检查有关的错误,尤其如此。 Swift 5.2通过专注于类型检查器的改进解决了这个问题。

    简化故障排除

    看看下面的SwiftUI代码:

    struct SquareView : View {
      @State var angle = 0.0
      
      var body: some View {
        VStack {
          TextField("Angle:", text: $angle)
          Rectangle()
            .rotation(Angle(degrees: angle))
            .frame(width: 100.0, height: 100.0)
        }
      }
    }
    
    

    在Xcode 11.4之前,您将看到的错误消息是

    image.png

    不是很有帮助,是吗?在使用SwiftUI时,经常会看到诸如此类的不清楚的错误消息。这使得使用SwiftUI变得更加困难。找到最简单的错别字就成了繁琐的重新读取,删除或注释掉代码以隔离实际错误的过程。

    再看一下代码块。您能发现实际问题吗?提示,与将Double转换为CGFloat无关!

    在xcode 11.4您会看到编译器为您提供了更有用,更可行的错误消息:

    image.png

    错误消息会指出错误所在的正确行,并告诉您问题所在:您正在将Double的绑定传递给期望与String绑定的方法。

    TextField("Angle", value: $angle, formatter: NumberFormatter.decimalFormatter)
    
    

    不只是SwiftUI

    虽然您通常会在SwiftUI中注意到更好的错误消息传递,但是您还将看到其他Swift代码的改进。

    let x: [Int] = [1, 2, 3, 4]
    let w: UInt = 4
    
    let filtered = x.filter { ($0 + w)  > 42 }
    
    

    此代码尝试在不进行强制转换的情况下将Int添加到UInt,并且将无法编译。在Swift 5.2之前,编译器显示以下错误:

    error: binary operator '+' cannot be applied to operands of type 'Int' and 'UInt'
    

    现在您将看到更精确,更有用的错误消息

    error: new-features.playground:34:22: error: cannot convert value of type 'UInt' to expected argument type 'Int'
    _ = x.filter { ($0 + y) > 42 }
    ^
    Int( )
    
    

    新的语法糖

    Swift已经在语言中内置了很多语法糖。 Swift 5.2引入了两个新功能,某些开发人员会发现它们非常方便,从而增加了此功能:将类型调用为函数并将键路径表达式用作函数。

    注意:语法糖会更改语言的语法,以使其更易于理解或更简洁。

    Calling Types as Functions

    这项新功能为Swift引入了可静态调用的值。但是,这是什么意思?好吧,这意味着您可以像调用函数一样调用类或其他结构。

    要在代码中实现此功能,请向该类型添加一个名为callAsFunction(_ :)的方法。而已!没有第二步。

    通过此添加,您现在可以将值作为函数调用。例如,采用代表二次方程的这种类型-一个以ax ^ 2 + bx + c形式表示的常见数学函数:

    struct Quadratic {
      var a: Double
      var b: Double
      var c: Double
    
      func callAsFunction(_ x: Double) -> Double {
        a * pow(x, 2) + b * x + c
      }
    }
    
    

    定义类型使用任何其他值:

    let f = Quadratic(a: 4, b: 4, c: 3)
    
    

    请注意,添加callAsFunction(_:)不会阻止您使用默认 init() 方法。
    ·

    此示例的数学类型选择不是巧合。使用类似于数学表示法的语法是此功能的主要动机。

    let y = f(5)
    
    

    与任何方法一样,可以有多个重写调用callAsFunction(:)以您的类型。如果还希望计算双精度数组的值并将结果作为新数组返回,则可以添加 callAsFunction(:)的第二个:

    func callAsFunction(_ xs: [Double]) -> [Double] {
      xs.map { callAsFunction($0) }
    }
    
    

    此代码采用双倍数组,并使用 map() 和callAsFunction(_:)的上一个实现(*:)生成具有结果的数组。Swift 确定调用的合适方法,就像对任何其他重写函数调用一样.

    let z = f([5, 7, 9])
    
    

    更简洁的语法

    通过在此方法上添加传统方法,可以实现此功能的相同结果。但是,新的语法更简洁,尤其是在值有单个明显操作的情况下。在此示例中,对二次类型的明显操作是计算给定 x 的方程的值。同样,Parser 通常会解析输入作为其主要函数。

    机器学习应用

    此功能似乎特别侧重于机器学习。在原始建议中,您会看到这一点,因为它特别提到清理神经网络应用程序的语法。它类似于 Python 和交叉兼容。所有这些都使 Swift 更适合 ML 开发人员。

    更多细节可参考,Callable values of user-defined nominal types

    Key Path Expressions as Functions

    Swift 5.2现在允许 \Root.value 键路径表达式,只要您已经可以使用 (Root)-> Value函数。

    在Code术语中,您可以编写:

    orders.map { $0.email }
    
    

    现在您可以写成

    orders.map(\.email)
    
    

    当前实现将此功能限制为键路径文本表达式。您当前无法编写以下内容,但此功能的讨论建议将来实现

    let kp = \.email
    users.map(kp)
    
    

    但是,您可以使用不同的语法完成类似的事情:

    let asEmail: (Order) -> String = \Order.email
    orders.map(asEmail)
    
    

    小结

    前两个功能为 Swift 带来了更好的功能能力。现在,您可以在以前需要块或闭包的地方使用函数。由于现在可以将key path作为函数传递,因此还可以将key path 传递给实现callAsFunction()。

    更多关于key path,请参考《Key Path Expressions as Functions》

    Subscripts With Default Arguments

    使用 Swift 5.2,现在可以在为类型添加自定义子脚本时声明默认参数。例如,下面是一种使用子脚本进行乘法的简单类型

    struct Multiplier {
      subscript(x: Int, y: Int = 1) -> Int {
        x * y
      }
    }
    
    let multiplier = Multiplier()
    
    

    此添加允许您编写指定任意数量的可用子脚本的代码。Swift 对未指定的任何下标使用提供的默认值

    multiplier[2, 3]
    multiplier[4]
    
    

    更多subscript请参考https://bugs.swift.org/browse/SR-6118

    资料

    如果您想了解有关 Swift 进化过程的更多信息,请查看以下链接:

    技术交流

    QQ:3365059189
    SwiftUI技术交流QQ群:518696470

    推荐文章

    CoreData篇

    TextField篇

    JSON文件篇

    相关文章

      网友评论

        本文标题:SwiftUI内功之Swift5.2 给我们带来了什么新惊喜

        本文链接:https://www.haomeiwen.com/subject/tbjcwhtx.html