前语

本期是 Swift 修改组自主收拾周报的第十七期,每个模块已初步成型。各位读者假如有好的提议,欢迎在文末留言。

欢迎投稿或引荐内容。现在计划每两周周一发布,欢迎情投意合的朋友一同加入周报收拾。

考验人的才干不在于他是否拿到一副好牌,而在于他能打好一副坏牌。挑选Swift社区,教你打好人生的每一张卡牌!

周报精选

新闻和社区:WWDC23 将于北京时间 6 月 6 日举办

提案:提出增加 Value 和 Type 参数包

Swift 论坛:评论 KeyPath 会发生内存走漏吗?

引荐博文:运用 Hummingbird framework 对数据进行编码和解码

论题评论:

今世大学生脱掉孔乙己长衫,挑选一般的非技能岗位作业,这算是一种思维的前进吗?

新闻和社区

WWDC23 将于北京时间 6 月 6 日举办

Swift 周报 第二十六期

万勿错失北京时间 6 月 6 日至 10 日为期一周五光十色的技能和社区活动,现在就增加到你的日历吧。你将能抢先了解 Apple 渠道、技能和东西的最新动态,还有机会与 Apple 专家和其他开发者互动。以上活动均免费在线举办。

此外,Apple 将于太平洋夏令时间 6 月 5 日在 Apple Park 举办面向开发者和学生的全天特别活动。咱们将一同观看主题演和解 State of the Union 视频,与部分 Apple 团队会晤交流,在 Apple 设计大奖颁奖典礼上为杰出的 App 欢呼庆祝,还能一同乐享当晚的活动。

别的,富有才华的学生们还可经过展现自己的创造力,比赛 Swift Student Challenge 并取得奖赏。

4 月 25 日起将实行以下 App Store 内容提交要求

自 2023 年 4 月 25 日起,提交至 App Store 的 iOS、iPadOS 和 watchOS App 有必要运用 Xcode 14.1 或更高版别构建。你能够从 Mac App Store 中免费取得最新版别的 Xcode 14,其间包含适用于 iOS 16、iPadOS 16 和 watchOS 9 的最新 SDK。

当你构建 App 时,咱们强烈主张你运用 iOS 16、iPadOS 16 和 watchOS 9 中的最新改进。

iOS 16 满载全新的个性化功用、更具深度的智能技能,以及更多无缝式的交流与同享方式,让 iPhone 的体会更进一步。运用“实时活动”帮助用户经过 iPhone 14 Pro 上的确认屏幕和灵动岛,直接了解你的 App 中正在发生的作业。凭借 App Intents,用户能够经过语音或轻点方式快速完成与你的 App 相关的使命。此外,你还能够充分运用 MapKit、ARKit 和 Core ML 等技能中的最新增强功用。

iPadOS 16 引入了新的功率功用,让你能够在 iPad 上供给引人入胜的协作体会,构建更丰厚、更直观的 App 和强壮的专业作业流程。你能够为 iPad App 带来桌面级功用,如修改器风格的导航栏、增强的文本修改菜单和外置显示器支持。同时,Metal 3 也引入了多项强壮功用,可帮忙你的游戏和专业 App 在最新一代的 iPad Pro 和 iPad Air 上充分开掘 Apple 芯片的潜能。

watchOS 9 为 watchOS App 供给了强壮的新通信功用。你能够在更多 Apple Watch 表盘上经过丰厚的复杂功用供给及时资讯,支持用户从你的 App 中分享内容,让用户直接经过 Apple Watch 进行 VoIP 通话等。此外,watchOS App 的结构经过简化,更是让办理项目变得前所未有的简略。

提案

驳回的提案

SE-0385 自界说反射元数据 提案被驳回。该提案已在 二十二期周报 正在检查的提案模块做了具体介绍。

正在检查的提案

SE-0393 Value 和 Type 参数包 提案正在检查。

该提案增加了类型参数包和值参数包,方便对 Value 和 Type进行抽象完成。这是 Swift 向可变泛型迈出的关键一步。

Swift论坛

  1. 提议使 Never 符合 Codable

介绍

扩展 Never 使其符合 Encodable 和 Decodable 协议,统称为 Codable。

动机

Swift 能够为任何具有 Codable 成员的类型归纳 Codable 一致性。 泛型类型通常经过束缚它们的泛型参数来参与这种归纳一致性,例如 Either 类型:

enum Either<A, B> {
    case left(A)
    case right(B)
}
extension Either: Codable where A: Codable, B: Codable {}

这样,两个泛型参数都是 Codable 的 Either 实例本身便是 Codable,例如 Either<Int, Double>。 但是,因为 Never 不行编码,因而运用 Never 作为参数之一会阻止条件一致性,即使编码或解码像 Either<Int, Never> 这样的类型是彻底没问题的。

主张的解决方案

标准库应该向 Never 类型增加 Encodable 和 Decodable 一致性。

具体设计

Encodable 一致性很简略——因为不行能有 Never 实例,encode(to:) 办法能够简略地为空。 Decodable 协议需求 init(from:) 初始化器,它显然不能创立 Never 实例。 假如尝试解码,该完成会抛出 DecodingError。

  1. 提议导入带有 ARC 指针成员的 C 结构体

介绍:

现在,Swift 能够导入 C 结构,其成员是 Swift 可导入的值类型,例如 int、BOOL 和 __unsafe_unretained ARC 指针,它们都是简略的结构和可析构的。 根据 Akira 在 LLVM 中启用强引证和弱引证的作业,咱们应该能够导入这些类型和声明。

动机:

自 2018 年以来,这些指针类型已可用于 Objective-C/Objective-C++(以及之前的 Objective-C++),而 Swift 迄今为止没有扩展以导入它们。 这是 Swift <> C++ 互操作的必要部分,咱们应该能够移植值类型的引证类型成员的默许和成员结构和销毁,包含 Objective-C 言语形式中结构中的 ARC 指针。 Puyan 已经在此处兼并了一些运用 C++ interop 构建这些类型的代码。

主张的解决方案:

#import <Foundation/Foundation.h>
typedef struct WithArcPointers {
    __unsafe_unretained NSString *usUR;
    __strong _Nonnull NSString *sStr;
    __weak _Nullable NSString *wStr;
    NSInteger count;
} WithArcPointers;

应该导入到 Swift 作为

struct WithArcPointers {
  init(usUR: String!, sStr: String, wStr: String?, count: Int)
  var usUR: Unmanaged<NSString>!
  var sStr: String
  weak var wStr: NSString?
  var count: Int
}

应保存各种 arc 存储类型,并在或许的状况下尊重预期的类型桥接和可空性注释。 弱成员在 Swift 端有必要是 Optional,而且 __unsafe_unretained 有必要对错桥接类型的 Unmanaged。 这些结构应该是成员可结构的,假如它们不包含非空成员,那么也能够经过可用的 init() 轻松结构。

结构中的非空弱引证虽然在 Clang 中是合法的,但不会被导入而且编译器将宣布恰当的确诊,因为 Swift 要求弱引证是可选的。 C 声明或许也应该有一个确诊,与恰当过错的 ObjC 类一致,但这超出了本提案的规模。

  1. 提议可变序列

Swift 能够经过在办法界说中允许重复的参数序列来使可变参数表达式更强壮。

这是在 Swift 5.7 语法中有效的可变参数函数界说和调用:

func myFunction(_ value: (name: String, age: Int)..., and otherName: String) {}
myFunction((name: "Ada", age: 26), (name: "Bob", age: 21), and: "Carl")

但是,我信任相同的界说/调用应该具有如下所示的才能:

func myFunction(name: String..., age: ...Int, and anotherParameter: String) {}
myFunction(name: "Ada", age: 26, name: "Bob", age: 21, and: "Carl")

这或许是一种称为可变序列的新言语功用,其间能够在办法界说中包含恣意数量的序列参数。 请注意新的 …Int 语法:这表明可变序列的结尾。 此功用为开发人员在编写办法调用时供给了更友好的体会。

至于在函数完成中获取可变参数序列,能够运用美元符号语法。 或许,每个可变序列元素都能够经过参数名称作为元组数组取得。 最终,能够经过运用 for in 循环 [1] 来迭代可变序列。

func myFunction(a: String..., b: ...Int) {
  let allSequences: [(a: String, b: Int)] = $0
  let allValuesOfA: [String] = a
  let allValuesOfB: [Int] = b
  for myA, myB in $0 {
    let aValue: String = myA
    let bValue: Int = myB
  }
}

提议的细节:

每个可变参数序列都以翻开和封闭参数开始和完毕。 开放参数运用 Type… 语法。 封闭参数运用新的 …Type 语法。

func myFunction(_ open: String..., _ close: ...String) {}

可变序列能够包含中间参数。 中间参数的类型运用一般语法:

// Variadic sequence with 3 elements
func myFunction(_ open: String..., _ middle: String, _ close: ...String) {}
// Variadic sequence with 4 elements
func myFunction(_ a: String..., _ b: String, _ c: String, _ d: ...String) {}

可变参数序列能够运用任何需求的类型。

func myFunction<T>(_ a: String..., _ b: Double, _ c: ...T, _ d: Int) {}
myFunction("Swift", 5.7, objectA, "Objective-C", 2.0, objectB, 1234)

对具有可变序列参数的函数的调用能够根据需求包含尽或许多的重复:

myFunction("A", 1, "B", 2, "C", 3, "D", 4) {}

Varadic 序列元素能够命名为 [2]:

func myFunction<A, B>(property path: KeyPath<A, B>..., _ middle: Comparison, value: ...B) {}
myFunction(property: \.name, .equals, value: "Ada", property: \.age, .greaterThan, value: 21)

办法界说中或许存在多个不同长度的可变序列。 在这种状况下,每个相应的序列都是运用 0、0、1、$2 等取得的:

func myFunction(_ a: String..., _ b: ...Int, _ c: Double..., _d: Date, _ e: ...Int) {
  let abValues: [(String, Int)] = $0
  let cdeValues: [(Double, Date, Int)] = $1
}

可变参数序列能够与惯例参数和现有的可变参数一同运用:

func myFunction(_ a: String..., _ b: ...Int, _c: Double, _ d: Int...)
myFunction("Ada", 26, "Bob", 21, 5.7, 1, 2, 3, 4)
  1. 评论有没有办法从字符串中验证 URL

能够用第三方库:GitHub:vapor/validation

  1. 评论 KeyPath 会发生内存走漏吗?

答复:是的,KeyPath 实例在第一次运用时被缓存并保存在内存中直到程序完毕。

  1. 评论当序列元素为 Dictionary.Key 时,For-in 与 forEach()
extension Dictionary {
    func f1(keys: any Sequence<Key>) {
        for key in keys {
            let value = self[key]
        }
    }
    func f2(keys: any Sequence<Key>) {
        keys.forEach { key in
            let value = self[key]
        }
    }
}

在 for-in 中,key 的类型被揣度为 Any,而在 forEach() 中,其类型为 Key。 这是设计使然仍是过错?

答复:

首要,要知道这一点,但 f1 和 f2 实际上应该采用一些 Sequence 类型的参数,而不是任何类型的参数,这将使过错消失。 这是一个已知的限制,将来或许会被撤销。 让我试着分解一下。

从 f2: forEach 开始能够保存具体的 Key 类型,这要归功于 SE-0353:受限存在类型中的 Covariant Erasure with Constrained Existentials 1。 所以这是相对简略的。

对于 f1,编译器根本上将 for 循环重写为 while 循环,如下所示:

var iterator = keys.makeIterator()
while let key = iterator.next() {
    
}

假如咱们手动编写这个 while 循环,咱们会在第一行的 makeIterator() 调用中遇到过错:

过错:揣度成果类型“any IteratorProtocol”需求显式 因为通用要求的丢掉而导致的强制编译器强制咱们将 keys.makeIterator() 编写为任何 IteratorProtocol,以承认迭代器变量失去了其 Element == Key 的知识,这便是为什么 for 循环中的元素类型为 Any 的原因。

在 SE-0352: Implicitly Opened Existentials 中类型擦除成果值时“丢掉”束缚中描绘了几乎这种状况:

当触及翻开的存在类型的调用成果被类型擦除时,或许一些关于回来类型的信息无法用存在类型表明,因而上述“上界”将丢掉信息。

该部分还说到,未来的编译器版别能够经过恢复现在更多的类型信息来提高言语的表达才能。 它甚至清晰说到了或许有助于解决此问题的首要相关类型 SE-0353。

总而言之,当从任何 Sequence 生成迭代器时,编译器好像能够(而且最终应该)保存元素类型信息,但这没有完成(假如完成,它或许也会有 阅历 Swift Evolution)。

  1. 评论Void 作为相关类型?

引荐博文

在 Swift 中解决 The operation couldn’t be completed 过错

摘要: 本篇博客评论怎么解决 Swift 中出现 “The operation couldn’t be completed” 的过错,当收到 “The operation couldn’t be completed” 过错音讯时该怎么处理。作者解说说,这些过错通常会顺便过错代码,但没有描绘,因而很难确认怎么解决问题。该文章主张在GitHub上查找过错域以查找过错代码的描绘,然后在Google上查找相关信息并找到带有描绘的苹果文档。作者还介绍了 What The Error Code ,这是一个供给即时过错代码描绘的简略东西的运用。最终,作者解说说他们已经将 What The Error Code 增加到 RocketSim 上,以简化其运用。

Swift 之 struct 二进制巨细剖析

摘要: 文章评论了 struct 对比 class 的一些优劣势,重点剖析了 struct 和 class 对包体积带来的影响及躲避办法,并别离比较了运用 let 和 var 润饰下二者二进制巨细的区别,为咱们在日常开发中 struct 和 class 挑选上供给了包巨细维度的衡量。

运用 Hummingbird framework 对数据进行编码和解码

摘要: 这篇博文介绍了 HummingbirdFoundation 结构对数据进行编解码,它支持 HTML、JSON 和 plain text 等多种数据类型。该结构还允许将传入的 HTTP 恳求体目标轻松转换为 Swift 数据结构并回来它们。作者展现了结构经过 Codable 协议和运用 HBResponseCodable 协议、 HBResponseEncodable 协议、 HBRequestDecoderHBResponseEncoder 完成的 JSON 目标内置编码和解码支持。此外,文章还解说了运用 HummingbirdFoundation 支持的两种编码类型—— application/x-www-form-urlencodedmultipart/form-data—— 对 HTML 表单进行编码和解码。

在 Swift 中怎么撤销后台使命

摘要: 本文演示了在 Swift 5.5 中运用 async/await 异步编程时撤销后台使命的不同办法。文章强调了撤销不必要的使命的重要性,以避免不需求的后台使命搅扰应用程序的功能。文章供给了各种撤销使命的办法,包含运用撤销标志、运用 Task.checkCancellation() 检查使命撤销状况以及运用 Task.isCancelled 来将撤销传播到子使命。文章为每种办法供给了示例代码,并解说了每种办法的优点和缺陷。

论题评论

今世大学生脱掉孔乙己长衫,挑选一般的非技能岗位作业,这算是一种思维的前进吗?

  1. 有必要算啊,勇于突破陈旧观念,值得尊敬。
  2. 不能算的,挑选了一般非技能岗位,意味着自己的大学生计毫无价值体现。
  3. 无所谓前进与否,只不过是当今经济环境下的无奈挑选算了。

Swift 周报 第二十六期

欢迎在文末留言参与评论。

关于咱们

Swift社区是由 Swift 爱好者共同维护的公益安排,咱们在国内以微信公众号的运营为主,咱们会分享以 Swift实战SwiftUlSwift基础为核心的技能内容,也收拾搜集优异的学习资料。

特别感谢 Swift社区 修改部的每一位修改,感谢大家的辛苦支付,为 Swift社区 供给优质内容,为 Swift 言语的发展奉献自己的力量。

本文正在参加「金石计划」