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

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文件篇

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容