View in English

  • Apple 开发者
    • 入门汇总

    探索“入门汇总”

    • 概览
    • 学习
    • Apple Developer Program

    及时了解最新动态

    • 最新动态
    • 开发者你好
    • 平台

    探索“平台”

    • Apple 平台
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store

    精选

    • 设计
    • 分发
    • 游戏
    • 配件
    • 网页
    • Home
    • CarPlay 车载
    • 技术

    探索“技术”

    • 概览
    • Xcode
    • Swift
    • SwiftUI

    精选

    • 辅助功能
    • App Intents
    • Apple 智能
    • 游戏
    • 机器学习与 AI
    • 安全性
    • Xcode Cloud
    • 社区

    探索“社区”

    • 概览
    • “与 Apple 会面交流”活动
    • 社区主导的活动
    • 开发者论坛
    • 开源

    精选

    • WWDC
    • Swift Student Challenge
    • 开发者故事
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Centers
    • 文档

    探索“文档”

    • 文档库
    • 技术概述
    • 示例代码
    • 《人机界面指南》
    • 视频

    发布说明

    • 精选更新
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • Apple tvOS
    • Xcode
    • 下载

    探索“下载”

    • 所有下载
    • 操作系统
    • 应用程序
    • 设计资源

    精选

    • Xcode
    • TestFlight
    • 字体
    • SF Symbols
    • Icon Composer
    • 支持

    探索“支持”

    • 概览
    • 帮助指南
    • 开发者论坛
    • “反馈助理”
    • 联系我们

    精选

    • 《开发者账户帮助》
    • 《App 审核指南》
    • 《App Store Connect 帮助》
    • 即将实行的要求
    • 协议和准则
    • 系统状态
  • 快速链接

    • 活动
    • 新闻
    • 论坛
    • 示例代码
    • 视频
 

视频

打开菜单 关闭菜单
  • 专题
  • 所有视频
  • 关于

更多视频

  • 简介
  • 概要
  • 转写文稿
  • 代码
  • Swift 的新功能

    与我们一起了解 Swift 的最新更新。探索语言方面的最新进展,包括提升日常开发体验的更新、改进的并发性,以及更安全的高性能代码。了解工作流程和语言互操作性的改进,以及嵌入式 Swift 的更新。

    章节

    • 0:07 - Introduction
    • 0:44 - Everyday Language Improvements
    • 1:55 - anyAppleOS Availability
    • 3:02 - @diagnose Attribute
    • 3:52 - Module Selectors (::)
    • 5:59 - Library Updates
    • 6:16 - Standard Library
    • 7:31 - Swift Testing Updates
    • 9:29 - Subprocess 1.0
    • 10:14 - Foundation
    • 11:59 - Beyond Apple Platforms
    • 12:35 - Swift–C Interoperability (@C attribute)
    • 15:09 - Swift-Java
    • 16:03 - Editor support
    • 16:44 - WebAssembly (Wasm) & JavascriptKit
    • 18:08 - Embedded Swift
    • 19:59 - Performance Tuning
    • 21:29 - Optimizer Control: @inline(always) & @specialized
    • 24:29 - Ownership System & Noncopyable Types
    • 26:18 - Iterable Protocol & Borrow/Mutate Accessors
    • 28:57 - New Standard Library Types: UniqueBox, UniqueArray, Ref
    • 31:11 - The Future of Swift

    资源

    • Swift Blog
    • Explore documentation on swift.org
    • Swift Forums
      • 高清视频
      • 标清视频

    相关视频

    WWDC26

    • 使用 gRPC 和 Swift 构建实时 App 及服务
    • 迁移到 Swift Testing
  • 搜索此视频…

    你好 我是Swift团队的Becca 我和团队成员Evan来介绍 我们所做的一些改进 这些改进是在开发 Swift 6.3和6.4期间实现的 我先介绍语言层面的一些变化 这些变化将简化你日常的编码工作 然后Evan将介绍重要库的更新内容 以及Xcode和Apple平台之外 的支持进展 之后我将带你了解 一些专门用于调优的特性 让你在不牺牲安全性的前提下 优化性能敏感代码 最后由Evan来总结 介绍如何跟进或参与 Swift的开发工作 先从你可能每天都会用到的 一些简单改进开始 有些改进你几乎不会注意到 只会感觉某些小麻烦消失了 先来看看那些较小的变化 比如以前如果你想将some或any 与可选类型一起使用 就必须加上括号 这是由Swift的运算符优先级规则 导致的行为 但有点过于迂腐了 因此在Swift 6.4中 你可以直接去掉那些括号 编译器会将其理解为唯一合理的含义 如果你静默忽略了一个错误 现在会收到警告 这个错误来自Swift Concurrency任务 提醒你要么在任务中处理该错误 要么保存任务之后再检查错误 在defer块中调用async函数 的旧限制现已取消 如果你有一个类需要使用 @unchecked Sendable 因为它有一个weak var属性 现在你可以将该属性改为weak let 使其不可变 这样就不会妨碍你 使用Sendable检查了 或者如果某个类型不应该是Sendable 你可以使用新的波浪号Sendable语法 明确声明这一点 额外的好处是这不会阻止 子类成为Sendable 包含internal和private 混合属性的struct 现在将拥有第二个逐成员初始化器 可以在项目的其他文件中使用 但也有一些你肯定会注意到的变化 在过去二十年里 Apple生态系统不断成长 Swift代码中的可用性属性 也随之不断增多 去年Apple开始着手解决这个问题 通过对齐各OS版本的版本号来解决 现在Swift更进一步 让你将所有平台名称合并为一个 "Any Apple OS" 如果你关心的所有平台 可用性一致 你可以一次性指定所有OS 如有例外情况 可以用anyAppleOS 设置默认值 再为例外情况添加更具体的属性 这同样适用于#if os条件 如果你想完全排除某段代码的编译 随着时间推移另一个变化是API 随着API演进 旧版API有时会被废弃 提示你应该迁移到更新的版本 但有时你无法立即完成迁移 可能新API变化很大 需要时间来适应 如果能临时关闭这些警告 岂不是很好 而不影响项目的其他部分 现在你可以了 @diagnose属性让你可以 更改特定警告的行为 在特定声明的内部 你可以告诉Swift忽略 deprecated declaration警告组 让这类警告在该位置消失 你也可以用它有选择地启用 默认关闭的警告 例如你可以开启严格内存安全检查 在安全关键函数中 确保你已审计其中对unsafe API的使用 或者你可以将某些警告视为错误 这里我们将未来会成为错误的警告 提前升级 立即生效 这一切给了你极大的灵活性 Swift 6.3还有一个新特性 更好地处理两个模块 拥有同名API的情况 比如Rocket模块可能有一个类型 表示真实的百米高土星五号火箭 而GiftShopToys模块 有一个类型表示儿童尺寸的 土星五号火箭模型 如果在同一文件中 导入了这两个模块 Swift无法判断你要使用哪个 会给你报错 遇到这种情况时 你一直可以 通过点语法来澄清代码 Rocket.SaturnV会首先找到Rocket模块 然后在其中查找SaturnV类型 而不会注意到其他地方 还有另一个SaturnV 这通常有效 但在某些棘手情况下 会失效 比如如果Rocket模块也有一个Rocket类型 会怎样 我来告诉你会发生什么 Swift更倾向于类型名 而非模块名 因此它认为你指的一定是Rocket类型 然后在其中查找名为SaturnV的成员 找不到时就会报错 Swift 6.3有解决方案 只需将点改为双冒号 这种新语法叫做模块选择器 左侧的名称始终被视为模块名 Swift会忽略Rocket类型 直接找到Rocket模块 从那里可以轻松找到你要找的类型 这种语法也适用于 方法或属性的名称 当一个类型从两个不同模块的扩展中 获得同名方法时非常方便 毕竟调用错误的方法 真的会让人很头疼 模块选择器非常有用 尤其当两个你无法控制的 模块发生冲突时 比如SwiftUI和你使用的数据库包 都有一个叫View的类型 模块选择器能为你省去很多麻烦 防御性地使用它们也是个好主意 在宏展开和其他自动生成的代码中 因为你不知道项目中还导入了什么 但我们不建议你刻意将API 设计成有命名冲突 再依赖模块选择器来区分它们 即使你的代码无歧义 某些报错信息和文档 仍可能令人困惑 所以……不要这样做 了解了语言层面的新特性之后 接下来由Evan介绍 重要库的更新内容 这些语言改进都有一个共同目标 帮助你精确表达意图 减少多余的干扰 这一目标也延伸到了 你日常使用的库的更新中 标准库 Swift Testing Subprocess 以及Foundation

    先从标准库的更新说起 特别是任务取消的新工具 字典变换以及文件路径操作 在开始任何耗时工作之前 检查任务取消状态非常重要 在开始任何耗时工作之前 但有时候我们实际上 希望继续完成工作 即使任务已被取消 比如完成将数据写入磁盘 以避免文件损坏 现在你可以使用 任务取消屏蔽机制 在屏蔽范围内 任务取消检查始终返回false 保持这个区域尽量短暂很重要 专注于完成或回滚 已开始的工作 字典值映射也获得了更新 mapValues只将旧值 传入映射闭包 如果你需要键来计算新值 就不得不手动构建一个新字典 现在我们可以调用mapKeyedValues 它同时传入键和旧值 到映射闭包中计算新值 程序经常需要操作文件路径 不同平台表示文件路径的方式 存在细微差别 这使得正确处理它们颇具挑战 今年我们在标准库中 新增了一种文件路径类型 基于Swift System中的类型 让处理更加简便 Swift 6.4中的测试让你对 测试行为有了更多控制 允许你显示非致命问题 并动态跳过测试用例 现在你可以设置 Issue.record记录问题的严重级别 将其设置为警告 意味着你可以显示 测试用例中值得调查的问题 但不值得阻塞CI工作流 你可以通过调用Test.cancel API 动态取消测试 这在参数化测试中尤为强大 你可以取消不该运行 的单个参数 而不是让它们运行到完成 或令测试失败 有时你要处理的是不稳定的测试 swift test命令新增了 重复执行测试的功能 直到测试通过或失败 同时允许你控制最大重复次数 如果你指定重复直到测试通过 只有失败的测试会被重新运行 不会重新运行已通过的测试 节省时间 很多项目有大型测试套件 其中包含基于XCTest API构建的工具 在Swift 6.4中 XCTest断言失败 现在会作为测试问题上报 当从Swift Testing调用时 这意味着你可以迁移到Swift Testing 而不必担心在迁移过程中 意外丢失测试覆盖率 互操作性也在另一个方向有效 Swift Testing API 比如#expect宏 在XCTestCase中调用时同样有效 这意味着你可以用Swift Testing构建 辅助API 它们将具有一致 的行为 无论从XCTest还是 Swift Testing调用 如果你在现有项目中工作 你可能已经在从Swift Testing 调用XCTest断言 反之亦然 为了让这一过渡更加顺畅 这些问题默认作为警告上报 你可以在Xcode构建设置中 选择将其提升为测试失败 要了解更多关于Swift Testing 互操作性和迁移策略的内容 请查看"Migrate to Swift Testing" 去年我们宣布了Subprocess包 包含用于启动子进程的现代API 今年我们发布了Subprocess 1.0 融入了你们在实际使用中的反馈 API改进包括简化的执行类型 改进的错误处理 以及便捷API 用于轻松流式传输进程输出 跨平台支持也大幅提升 包括平台特定的进程文件描述符 和终止状态 更准确地反映 不同平台上的语义 这是Subprocess 1.0中 改进后API的示例 调用run方法启动子进程时 标准输出和标准错误流 可以作为AsyncBufferSequence 包含在执行对象中 这种模型保证每个流只创建一次 AsyncBufferSequence上的 新strings()方法 让你能够逐行读取子进程的输出 这个API尊重字形簇边界 你无需担心多字节字符被截断 最后来聊聊Foundation的改进 ProgressManager是Foundation中 用于进度报告的新类型 它专为与async/await 风格的并发良好协作而设计 它将进度组合与进度报告 清晰地分离开来 并提供结构化的 类型安全机制 用于附加额外元数据 两年前我们宣布了Swift-Foundation 致力于将Foundation迁移到 安全 一致 用Swift编写的跨平台代码库 今年我们延续了这一努力 用现代Swift替换了 数十年的Objective-C代码 今年我们对Data的更多部分 进行了现代化改造 带来了全面的性能提升 包括更快的Span访问 相等检查 遍历和修改操作 在Apple平台上 Data与NSData 之间的桥接也更快了 NSURL和CFURL已统一为 单一的Swift实现 借助Swift使这些类型 运行更快 占用内存更少 迁移像Foundation这样 庞大而成熟的库 得益于Swift的语言互操作性 才得以实现 你可以在Swift中添加全新API 并且可以迁移 在不改变API表面的情况下 将现有API的实现迁移到Swift 除了跨越语言边界之外 很多实际项目会延伸到 服务 设备 Web组件 跨平台客户端等各个方面 在Apple 我们在操作系统的 每个部分都使用Swift 在“天气”等App中 在实时 来电骚扰检测等服务中 在内核本身中 以及一直到 最底层的固件 Swift被设计为一门你可以 在各个场景使用的语言 贯穿你软件栈的每一层 为了让你在现有软件系统中 更容易使用Swift Swift 6.4扩展了语言互操作性 改进了跨平台IDE支持 让你更容易 更安全地将 Swift代码带到Web和嵌入式设备 等其他环境中 你一直可以轻松地将C导入Swift Swift 6.4允许你将 用Swift编写的函数导出回C 你可能见过或使用过@objc属性 在将App从Objective-C迁移到Swift时 @C属性的工作方式相同 只是针对C语言 @C属性适用于操作 C兼容类型的函数 任何你可以从C导入到Swift的类型 也可以用于从Swift导出到C的函数中 比如整数 指针 导入的C结构体 以及带有原始整数值类型的枚举 编译器还能防止你 意外传入与C不兼容的类型 与C不兼容的类型 让我们看看@C属性的实际效果 我正在开发一款用于 火箭发射调度的App 我们将重点关注 追踪发射窗口的代码 目前用C编写 但我们正在迁移到Swift 以提升内存安全性和开发者体验 让我们使用Swift 6.4的新特性 将应用程序的部分代码从C重写 目前头文件中声明了两个函数 一个用于获取发射窗口的时长 另一个用于计算 一组发射窗口的总时间 从而计算发射台利用率 先来替换C实现 即计算发射窗口时长的函数 我们可以同时使用@c和 @implementation属性 来实现C函数 而无需为其 创建C声明 因为它已经存在于 原始头文件中 接下来我们为计算函数 提供实现 即跨多个发射窗口计算 总停留时间的函数 在Swift中实现时 函数会被逐字导入 我们可以将类型 转换为原生Swift类型 从而利用Swift的便利性 重新实现我们的C函数 安全互操作特性在我们 调用函数时提供安全包装 因此不用分开传入数组和计数 而是可以直接传入span 写起来更简单 而且安全 在此过程中 我想添加一个获取 平均发射窗口时长的新函数 这里不使用@implementation属性 因为该函数未在 原始C头文件中声明 Swift编译器会将适当的 函数声明写入生成的C 互操作头文件中 这样我们就可以 从C代码中调用新函数 Swift会自动将Swift Span 桥接到C 现在 Swift C++互操作性也支持 Swift与C++ 20 span之间的桥接 这个声明以span形式导入Swift 你可以直接传入span 互操作性是关键 将Swift引入到用其他语言 编写的现有代码库的关键 Swift-Java是实现Swift与Java 互操作性的包 它现在支持从Java调用 async和throwing的Swift函数 它覆盖了泛型系统的更多特性 包括受约束的扩展 以及让Java类遵循Swift协议 所有这些改进 让在Android上从Java和Kotlin 调用Swift代码更加自然 你现在可以在swift.org上 下载适用于Android的官方Swift SDK 最新版本的VSCode Swift扩展 新增了与Swiftly的集成 让你可以直接在编辑器中 从swift.org安装工具链 这样你始终可以为任何平台 获取正确的工具链 触手可及 去年我们将Swift扩展 添加到了Visual Studio市场

    今年我们又将其添加到 OpenVSX市场 让集成的Swift体验可用于 包括以下在内的新编辑器 VSCodium Cursor Kiro和Antigravity 最新版本的插件让你开始 使用Swift比以往任何时候都更容易 通过检查列表引导你 完成Swift的安装 创建新项目 运行代码 设置测试以及生成文档 如果你安装了Swiftly 它可以帮助管理工具链 我正在安装一个nightly工具链 这样我就可以尝试面向 Web Assembly的新语言特性 和嵌入式平台 我们刚刚安装的开源工具链 可以编译到Web Assembly Swift对Wasm的支持 意味着你可以用同一种语言 编写原生App 后端Web服务器以及前端 让我们来看看Javascript 互操作性方面的一些改进 来自开源项目JavascriptKit Swift与Javascript之间的桥接 过去需要大量动态查找 并且只能寄希望于类型匹配 JavascriptKit最新的工作 使两种语言之间的桥接 更安全更快速 代码看起来像原生Swift代码 但它通过Javascript调用了WebGL

    广受欢迎的笔记App Goodnotes 最近在其原生iOS App之外 实现了一个基于Web的界面 将核心App迁移到另一种语言的成本 包括解决Bug和维护两套代码库 代价太高 他们直接使用经过实战检验的 现有Swift代码 使用Wasm将其编译到Web端 借助JavaScriptKit的改进 他们的基准测试发现 安全桥接比动态桥接 快35到40倍 Swift对Wasm的支持 意味着你可以将运行在 原生iOS应用中的Swift代码 并让它作为Web应用的一部分运行 但与原生应用不同的是 每次用户访问你的网站时 都需要向每台设备发送编译后的代码 CDN可以提供帮助 但大型二进制文件会很快 消耗你和用户的流量 这意味着文件大小 比以往任何时候都更重要 借助嵌入式Swift 我们可以在更受限的环境中 充分利用Swift的便利性 我们对语言进行了精简 以适应这些环境 现在随着我们了解到人们在这些 环境中使用Swift的方式 我们正在扩展可用的语言子集 嵌入式Swift现在支持存在类型 这意味着你可以处理 遵循协议的多个类型 存储在数组中或传递给函数 当你知道错误类型时 typed throws非常有用 但它们仅限于特定的错误类型 利用处理存在类型的相同底层机制 嵌入式Swift现在支持无类型throws 调试器需要关于类型布局的额外元数据 来显示变量 为了控制二进制文件大小 嵌入式Swift不在二进制文件 本身中包含该数据 此外很多嵌入式系统 只给你留下核心转储文件 记录程序崩溃时的内存状态 所以你甚至无法调试运行中的进程 Swift 6.4将所有必要的元数据 保存到DWARF调试信息中 保持二进制文件大小不变 同时大幅提升 嵌入式Swift核心转储的调试体验 这些只是我们今年所做的 一些改进 缩小完整Swift与 嵌入式Swift之间的差距 虽然适用于嵌入式平台的 Swift子集在不断增长 它仍然是语言的一个子集 EmbeddedRestrictions警告组中的 诊断信息能够识别语言特性 在嵌入式上下文中 不可用的语言特性 如果你在使用同时支持 嵌入式和完整Swift的库 你可能需要暴露一些函数 使用了嵌入式上下文中 不可用的特性 Becca之前展示的@diagnose属性 让我们可以控制这些诊断信息 嵌入式代码通常运行在 极其受限的硬件环境中 因此充分利用每个时钟周期至关重要 回到Becca来介绍如何 榨取Swift代码的性能 Swift被设计为具有出色的性能 即使当你编写了最直接 最具表现力的逻辑实现时 但当你进行大量计算时 或在嵌入式系统等受限环境中运行时 有时值得让代码更复杂一些 在关键时刻榨取更多性能 你通常不需要这些高级性能特性 但需要时你会庆幸有它们

    我将重点介绍今年我们工作的两个方面 明确控制优化器的决策 以及进一步扩展所有权系统 安全地防止不必要的拷贝 Swift编译器的优化器 应用数十种技术使你的代码更快 但其中一些最强大的技术 如果应用不当 可能会适得其反 这些技术涉及复制代码 以便针对特定情况进行定制 但如果定制没有收益 最终可能得到一个 更大更慢的程序 而非更小更快的 例如 编译器执行的最重要优化之一 是内联 用函数的实现替换函数调用 然后针对特定调用点 优化这些实现 当内联有收益时 程序完成相同结果所需工作更少 但当没有收益时 只会使二进制文件变大 而不会变快 为了防止这种情况发生 优化器会分析函数和调用点 来决定内联是否可能有收益 但有时它会做出错误的决定 所以你可能希望有一种方式 来强制指定 Swift早就有@inline(never)属性 完全禁止内联 当你知道内联该函数 永远不会带来收益时非常有用 在Swift 6.4中现在有了 对应的@inline(always)属性 强制编译器进行内联 即使优化器不确定 这是否是个好主意 但有时它仍然无法做到 比如调用可能被重写的对象方法时 因此对类的方法考虑将final 与@inline(always)结合使用 另一个重要的优化是特化 为特定具体类型克隆泛型函数 消除泛型开销 并通常支持进一步优化 函数特化只有在以下情况才有效 当优化器知道你将用该类型使用它时 但有时 尤其是在库中 编译器无法看到 函数将如何被使用 Swift 6.3引入了@specialized属性 让你直接控制这一点 在该属性内部 你编写一个where子句来约束 部分或所有泛型参数 Swift将生成该函数的特化版本 包含这些约束 如果你有一些慢速的泛型代码 经常与一两种特定类型一起使用 你可以让Swift知道 它需要优先处理这些类型 但我们在性能调优方面 做出的最大改进 是对所有权系统的改进 为了理解我们做了什么 先来回顾一下我们已有的内容 Swift中的很多性能问题 归根结底是不必要的数据拷贝 你在一处有一份数据 在另一处需要它 于是你将数据拷贝 到新的存储位置 有时这些组件很大 比如App的模型层和视图层 有时它们很小 比如for循环in关键字 两侧的两个变量 但基本模式是相同的 解决由拷贝引起的性能下降 关键是认识到 在某些情况下 拷贝是不必要的 如果你知道存储会保持分配状态 并且使用它的两个组件都将 遵循Swift的排他性规则 不修改双方都能访问的数据 那么你就不需要拷贝数据 只需授予对现有存储的访问权限 避免拷贝最简单的方式 是将数据放入对象中 并将该对象传递给另一个组件 这通常已经足够 但并不能完全消除问题 毕竟对象是引用计数的 传递对象会改变其引用计数 释放和持有对象的开销 比拷贝大型值要小 但对于最性能敏感的代码 仍然可能太慢 当对象不是选项时 传统上你不得不传递 UnsafePointer指向存储 但这样做的问题就在其名称中 UnsafePointer是不安全的 像这样共享存储只在以下情况安全 当两个组件都遵循某些规则时 但编译器不了解这些规则 无法确保 每一方都能履行约定 组件1可能修改组件2 期望保持不变的数据 或者在组件2仍在使用时 释放存储 你又回到了没有内存安全的世界 就像C语言那样

    因此几年前我们开始研究 一个更好的解决方案 我们将安全共享存储所需的 一组保证规范化为借用 只要组件2在借用存储 两个组件都只能读取它 不能写入 组件2必须先完成对存储的使用 当完成后 组件1 重新获得完全控制权 修改也类似 只是另一个组件被完全阻止 访问存储 这确保它不会读到半更新的数据 或产生不同的行为 取决于另一个组件何时 写回其更改 无论是借用还是修改 Swift都可以在编译时验证 两个组件都遵循规则

    但我们的目标一直是 支持这些高级用例 而不影响你编写 普通Swift代码的方式 这需要对所有权特性进行 谨慎的增量式设计 这是一个多年的过程 目前仍在继续 但今年我们又迈出了几步 例如Equatable Comparable和Hashable协议 现在可以用于不可拷贝类型 Equatable和Comparable也可以 用于不可逃逸类型 这让为性能和安全性而优化的类型 能够利用一些最通用的功能 这些是普通Swift类型所具备的 关联类型现在也可以是 不可拷贝或不可逃逸的 这开启了强大的新功能 用于高性能的协议驱动开发 就像这里的Iterable协议 其元素类型是不可拷贝的 其迭代器类型既不可拷贝 也不可逃逸 当然这并不意味着你不能 为此使用可拷贝或可逃逸类型 只是意味着协议不做此要求 哇 那个Iterable类型 看起来真的很好用 你是不是希望它是真实的 好消息 它确实是 在Swift 6.4中 for循环支持 新的Iterable协议 我们都熟悉的Sequence协议 通过从序列中拷贝元素来工作 而Iterable协议允许 for循环改为借用它们 这意味着它可以处理不可拷贝的元素 而且不需要执行引用计数 当处理对象或写时拷贝类型时 另外它可以选择在循环中抛出错误 就像ASYNC Sequence一样 然而像任何借用一样 排他性检查禁止你修改Iterable 在你遍历它的时候 这不一定是坏事 因为这在Sequence中 常常是个性能陷阱 由于这种行为差异 for循环会优先使用Sequence协议 (如果可用) 否则回退到Iterable 与Sequence类似 Iterable 通过创建迭代器来工作 供for循环从中检索元素 但与sequence不同 它以批次方式检索元素 for循环会向迭代器请求 一个span的元素 然后逐一处理 然后再请求另一个span 同样逐一处理 当元素耗尽时 返回一个空span 这终止了for循环 这种批量设计使循环效率大幅提升 尤其对于可以在一个大span中 返回所有内容的类型 Swift 6.4还对访问器 进行了重大改进 为了理解其重要性 考虑这个UniqueBox结构体 它自动管理一个指向大型值的指针 并提供一个计算属性来访问它 不幸的是按现在的写法 这个属性有一个严重的性能问题 让我们看看原因 假设你在UniqueBox中放入 一个包含256个Int的InlineArray InlineArray是内联的 所以在64位设备上 那将是一个两千字节的结构体 不是你想一直到处拷贝的东西 这是个问题 因为get和set 通过拷贝数据来工作 要修改数组中的一个Int 你必须先将整个结构体 拷贝出去再拷贝回来 这对性能没什么帮助 幸运的是现在有了更好的选项 你可以从get和set切换 到borrow和mutate 新的borrow访问器让你 对共享存储进行只读访问 无需拷贝 而mutate访问器让你 独占访问并原地修改它 切换之后 Swift可以直接修改原始数组中的元素 无需拷贝任何内容 作为额外的好处 新的访问器意味着UniqueBox 也可以处理不可拷贝的值 borrow和mutate访问器 对性能和表达力都有很大帮助 我们很高兴它们已经准备好 供大家使用了 哇 那个UniqueBox类型 看起来真的很好用 你是不是希望…… 好吧 好吧 你知道结果是什么 我不再重复那段台词了 是的 UniqueBox是真实的类型 现已纳入标准库 还有一些其他新API 让你无需编写不安全代码 "Unique Array"非常像 普通的Swift数组 只是它是不可拷贝的 这意味着你可以存储不可拷贝的元素 并避免引用计数开销 而不限制自己使用固定大小 withTemporaryAllocation函数 使用OutputSpan而非 UnsafeMutableBufferPointer 确保临时内存的安全处理 Continuation类型在编译时检查 你只恢复它一次 这使其比CheckedContinuation更安全 但与UnsafeContinuation一样高效 还有另外一对类型我想告诉你们 但它们不是现有API的改进版 它们为语言带来了全新功能 Ref有点像Span 但针对单个值而非多个 它有点像借用或修改的容器 可以存储在变量中 从函数传入传出 并在泛型类型中使用 你可以通过借用存储 从读访问创建Ref类型的实例 或者通过写访问 创建MutableRef类型的实例 使用前缀&符号 这些类型可以用于创建 以前无法编写的新API 比如返回其某个属性 的MutableRef的方法 但它们也可以用于解决性能问题 例如考虑这个updateCount函数 每次需要递增时都会查找字典键 即使键始终是同一个 通常你希望将这类重复工作 提升到循环之外 这样只需执行一次 但直到现在 执行字典查找并保持它开放 一段时间的唯一方式 是将循环移入函数 并将查找作为inout参数传入 相当晦涩的技巧

    MutableRef给了你更好的方式 现在你可以从字典查找中 创建一次MutableRef 在循环开始之前 然后在需要修改字典条目时使用它 Ref是不可逃逸的 因此Swift知道访问结束 当变量超出作用域时 所有这些新的所有权特性结合起来 使加速最性能敏感的代码 比以往更安全更容易 所有权系统并不是 唯一仍在进行中的工作 让我们回到Evan来介绍 Swift的未来 我们今天介绍的特性 在开源社区中开发 改进了整体体验 覆盖Apple各OS Linux Windows及更多平台 以下是开源社区正在进行的 更多未来发展 你可以参与其中 去年 我们宣布了对Swift Build (Xcode中的构建系统)进行开源 Swift Build现在是 Swift Package Manager的默认构建系统后端 提升了Swift包构建 与Xcode之间的一致性 与Xcode中所见的一致性 加入不断增长的工作组行列的是 构建和打包工作组 解决Swift社区的 构建和打包需求 网络工作组 设计下一代跨平台网络API 以及Windows工作组 改善Swift在Windows上的体验 今年 Android工作组作为Swift 6.3的一部分 发布了首个适用于Android的Swift SDK 这意味着现在可以在Android和iOS 应用之间共享Swift代码 如果你有兴趣参与 Swift生态系统的开发 请在forums.swift.org 加入我们的Swift论坛 我们期待你独到的反馈 感谢你今天和我们一起 了解Swift的新特性 无论你是提交了Bug报告 发起了Pull Request 参与了活动 或者在论坛上讨论 你的贡献都在帮助塑造Swift的未来 让编程对每个人 都更安全,也更容易上手 谢谢大家

    • 1:12 - Better Swift Concurrency diagnostics (catching in the task)

      Task {
          do {
              try lander.fly(to: moon)
          }
          catch {
              lander.abort()
          }
      }
    • 1:21 - Better Swift Concurrency diagnostics (saving the task for later)

      let landingTask = Task {
          try lander.fly(to: moon)
      }
      
      defer {
          await orbiter.rendezvous(with: lander)
      }
      
      try await orbiter.justHangOut(waitingFor: landingTask)
    • 1:27 - Better 'Sendable' conformances

      final class Spacecraft: Sendable {
          ...
          weak let dockedAt: SpaceStation?
          ...
      }
      
      class Mission: ~Sendable { ... }
      
      class CrewedMission: Mission, @unchecked Sendable { ... }
    • 1:48 - More accessible memberwise initializers

      struct Briefing {
          internal var topic: String
          internal var scheduledAt: Date
          private  var attendees: [Person] = []
      }
      
      // Generated memberwise initializers:
      // extension Briefing {
      //     private init(topic: String, scheduledAt: Date, attendees: [Person] = []) { 
      //          self.topic = topic
      //          self.scheduledAt = scheduledAt
      //          self.attendees = attendees
      //     }
      // 
      //     internal init(topic: String, scheduledAt: Date) {
      //          self.topic = topic
      //          self.scheduledAt = scheduledAt
      //          self.attendees = []
      //     }
      // }
    • 2:03 - 'anyAppleOS' availability (before)

      extension Mission {
          @available(macOS 27, iOS 27, watchOS 27, tvOS 27, visionOS 27, *)
          func showStatus() { ... }
      
          @available(macOS 27, iOS 27, watchOS 27, visionOS 27, *)
          @available(tvOS, unavailable)
          func launch() { ... }
        
          #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
          func makeLiveActivityWidget() -> some Widget { ... }
          #endif
      }
    • 2:17 - 'anyAppleOS' availability (after)

      extension Mission {
          @available(anyAppleOS 27, *)
          func showStatus() { ... }
      
          @available(anyAppleOS 27, *)
          @available(tvOS, unavailable)
          func launch() { ... }
        
          #if os(anyAppleOS)
          func makeLiveActivityWidget() -> some Widget { ... }
          #endif
      }
    • 2:40 - Controlling warnings with '@diagnose'

      @diagnose(DeprecatedDeclaration, as: ignored, reason: "Flying with surplus hardware")
      func makeApolloSoyuzMission() -> Mission {
          CrewedMission(
              rocket: makeSaturnIRocket(),
              payload: makeApolloCSM(),
              crew: [.daniellePoole, .nathanMorrison]
          )
      }
      
      @diagnose(StrictMemorySafety, as: warning)
      func uplinkCommand(from receiver: inout Receiver, to computer: inout Computer) {
          let commandSize = receiver.receiveInt()
          receiver.withReceivedData(byteCount: commandSize) {
              computer.receiveUplinkedCommand($0)
          }
      }
      
      @diagnose(ErrorInFutureSwiftVersion, as: error)
      func fetchPosition() -> (x: Double, y: Double, z: Double) {
          return self.rotation
      }
    • 3:47 - Clarifying code with module selectors

      import Rocket
      import GiftShopToys
      
      let rocket1 = SaturnV()            // could mean `Rocket::SaturnV` or `GiftShopToys::SaturnV`
      let rocket2 = Rocket.SaturnV()     // prefers `Rocket::Rocket.SaturnV`
      let rocket3 = Rocket::SaturnV()    // correctly finds `Rocket::SaturnV`
    • 5:00 - Clarifying code with module selectors (module selectors work on members, too)

      //
      // Module Chemistry
      //
      
      public protocol Flammable { ... }
      
      extension Flammable {
          /// Set `self` on fire.
          public func fire() { ... }
      }
      
      //
      // Module HumanResources
      //
      
      import Chemistry
      
      public protocol Employee { ... }
      
      extension Employee {
          /// Remove `self` from job.
          public func fire() { ... }
      }
      
      public class LaunchPadTechnician: Employee, Flammable { ... }
      
      //
      // Module main
      //
      
      import HumanResources
      import Chemistry
      
      let launchPadTechnician = LaunchPadTechnician(...)
      
      launchPadTechnician.HumanResources::fire()
    • 6:26 - Task cancellation

      // Radio for help
      
      extension Radio {
        func send(_ data: [UInt8] {
          if Task.isCancelled { return }
          // ...
        }
      }
        
      extension EmergencyTransponder {
        func sendSOS() {
          radio.send(makeSOSPacket())
        }
      }
    • 6:40 - Task cancellation shield

      // Radio for help
      
      extension Radio {
        func send(_ data: [UInt8] {
          if Task.isCancelled { return }
          // ...
        }
      }
        
      extension EmergencyTransponder {
        func sendSOS() {
          withTaskCancellationShield {
          	radio.send(makeSOSPacket())
          }
        }
      }
    • 6:53 - Constructing a new dictionary

      // Map values with keys
      
      func makeCalendarDisplayNames(for missions: [Mission: LaunchWindow]) -> [Mission: String] {
          let new: [Mission: String] = .init(
              uniqueKeysWithValues: missions.lazy.map { mission, launchWindow in
                  (mission, makeDisplayName(for: mission, in: launchWindow))
              }
          )
          return new
      }
    • 7:06 - Dictionary.mapKeyedValues

      // Map values with keys
      
      func makeCalendarDisplayNames(for missions: [Mission: LaunchWindow]) -> [Mission: String] {
          missions.mapKeyedValues { mission, launchWindow in
              makeDisplayName(for: mission, in: launchWindow)
          }
      }
    • 7:14 - The new FilePath type

      // FilePath handling macOS-named resources
      
      var path: FilePath = "/var/www/static"
      path.components.append("WWDC")
      print(path.components)
      // [ "var", "www", "static", "WWDC" ]
      
      var path: FilePath = "/var/www/static/..namedresource/rsrc"
      print(path.components)
      // [ "var", "www", "static" ]
    • 7:41 - Issue Severity

      // Issue severity
      
      @Test(arguments: allRockets)
      func testBurn(rocket: Rocket) throws {
          rocket.burn(for: .seconds(150))
          let remaining = rocket.propellantKg / rocket.totalPropellantKg
      
          if remaining < 0.10 {
              Issue.record(
                  "\(rocket.name) remaining fuel is below 10% reserve target",
                  severity: .warning
              )
          }
      
          #expect(remaining > 0.02, "\(rocket.name) propellant critically low - abort")
      }
    • 7:52 - Test Cancellation

      // Test Cancellation
      
      @Test(arguments: allRockets)
      func testBurn(rocket: Rocket) throws {
          // solid-fuel rocket engines can't be stopped
          if rocket.engineType == .solid {
              try Test.cancel("\(rocket.name) has solid fuel")
          }
       
          rocket.burn(for: .seconds(150))
          let remaining = rocket.propellantKg / rocket.totalPropellantKg
      
          if remaining < 0.10 {
              Issue.record(
                  "\(rocket.name) remaining fuel is below 10% reserve target",
                  severity: .warning
              )
          }
      
          #expect(remaining > 0.02, "\(rocket.name) propellant critically low - abort")
      }
    • 8:34 - XCTest interoperability: Using XCTest from Swift Testing

      // XCTest interoperability: Using XCTest from Swift Testing
      
      func checkedTransmitAndReceive(on radio: Radio,
                                     packet: Packet,
                                     expectedByteCount: Int) throws -> [UInt8] {
          try radio.transmit(bytes: packet.data)
          let bytes = try radio.receive()
          XCTAssertEqual(bytes.count, expectedByteCount)
          return bytes
      }
      
      @Test
      func pingTest() throws {
          let radio = Radio()
          let bytes = try checkedTransmitAndReceive(on: radio, packet: .ping, expectedByteCount: 8)
          #expect(bytes == [0x00, 0x00, 0xf0, 0x37, 0x0f, 0xc7, 0x00, 0x01])
      }
    • 8:48 - XCTest interoperability: Using Swift Testing from XCTest

      // XCTest interoperability: Using Swift Testing from XCTest
      
      class RadioTests: XCTestCase {
          func testPingPacketTransmission() {
              let radio = Radio()
              let bytes = try checkedTransmitAndReceive(on: radio,
                                                        packet: .ping,
                                                        expectedByteCount: 8)
      
              #expect(bytes == [0x00, 0x00, 0xf0, 0x36, 0x0f, 0xc7, 0x00, 0x02])
          }
      }
    • 10:01 - Subprocess Output Stream

      // Subprocess output streaming
      
      let result = try await Subprocess.run(.name("ls"),
                                            input: .none,
                                            output: .sequence,
                                            error: .string(limit:4096)) { execution in
      		execution.standardOtput.strings().filter { $0.hasSuffix(".obj") }
      }
      
      for try await objectFiles in result.closureOutput {
        	print("Object file: \(objectFile)")
      }
    • 10:37 - Progress Manager - Concurrency

      // Progress reporting - Concurrency
      
      let manager = ProgressManager(totalCount: 100)
      try await rocket.launch(mission.subprogress(assigningCount: 100))
      
      extension Rocket {
          func launch(_ progress: consuming Subprogress? = nil) async throws {
              let stage = progress?.start(totalCount: 3)
              try await ignite(); stage?.complete(count: 1)
              try await liftoff(); stage?.complete(count: 1)
              try await stageSeparation(); stage?.complete(count: 1)
          }
      }
    • 10:37 - Progress Manager - progress reporting

      // Progress reporting - progress reporting
      
      let manager = ProgressManager(totalCount: 100)
      try await rocket.launch(mission.subprogress(assigningCount: 100))
      
      Task {
          for await update in Observations({ mission.fractionCompleted }) {
              print("🚀 Mission \(Int(update * 100))%")
          }
      }
    • 10:37 - Progress reporting - metadata

      // Progress reporting - metadata
      
      extension Rocket {
          func ascend(_ progress: consuming Subprogress) async throws {
              let stage = progress.start(totalCount: 3)
              stage.detlaV = 3_400; try await burn(); stage.complete(count: 1)
              stage.detlaV = 2_100; try await stageSeparation(); stage.complete(count: 1)
              stage.detlaV = 1_800; try await coast(); stage.complete(count: 1)
          }
      }
      
      print("Δv to orbit: \(mission.summary(of: \.deltaV)) m/s")
    • 20:56 - Directly control inlining (source code)

      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = makeInts(randomized: false)
        
          for value in values {
              result[Int(value)] += 1
          }
        
          return result
      }
      
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:01 - Directly control inlining (inlined, but not optimized)

      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = if false {                                                  //
                           InlineArray { _ in Int.random(in: (.min)...(.max)) }    //
                       } else {                                                    // Inlined code
                           InlineArray(repeating: 0)                               //
                       }                                                           //
      
         for value in values {
              result[Int(value)] += 1
          }
          return result
      }
      
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:07 - Directly control inlining (inlined and optimized)

      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = InlineArray(repeating: 0)    // Inlined and optimized code
      
         for value in values {
              result[Int(value)] += 1
          }
          return result
      }
      
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:30 - Directly control inlining (preventing inlining)

      @inline(never)
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:39 - Directly control inlining (forcing inlining)

      @inline(always)
      func makeInts(randomized: Bool) -> [256 of Int] {
          if randomized {
              InlineArray { _ in Int.random(in: (.min)...(.max)) }
          } else {
              InlineArray(repeating: 0)
          }
      }
    • 21:55 - Making generic functions faster with '@specialized'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = makeInts(randomized: false)
        
          for value in values {
              result[Int(value)] += 1
          }
        
          return result
      }
      
      // Note: Specialized function doesn't actually have a directly callable name.
      func `histogram of [UInt8]`(of values: [UInt8]) -> [256 of Int] {    //
          var result = makeInts(randomized: false)                         //
                                                                           //
          for value in values {                                            //
              result[Int(value)] += 1                                      // Specialized code
          }                                                                //
                                                                           //
          return result                                                    //
      }                                                                    //
    • 22:17 - Making generic functions faster with '@specialized'​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ (explicitly requesting specialization)

      @specialized(where Values == [UInt8])
      func histogram<Values>(of values: Values) -> [256 of Int] where Values: Sequence<UInt8> {
          var result = makeInts(randomized: false)
        
          for value in values {
              result[Int(value)] += 1
          }
        
          return result
      }
      
      // Note: Specialized function doesn't actually have a directly callable name.
      func `histogram of [UInt8]`(of values: [UInt8]) -> [256 of Int] {    //
          var result = makeInts(randomized: false)                         //
                                                                           //
          for value in values {                                            //
              result[Int(value)] += 1                                      // Specialized code
          }                                                                //
                                                                           //
          return result                                                    //
      }                                                                    //
    • 25:46 - Associated types can be '~Copyable' and '~Escapable'

      protocol Iterable<Element, Failure>: ~Copyable, ~Escapable {
          associatedtype Element: ~Copyable
          associatedtype IterableIterator: IterableIteratorProtocol<Element, Failure>, ~Copyable, ~Escapable
          associatedtype Failure: Error = Never
      
          func makeIterableIterator() -> IterableIterator
        
          var underestimatedCount: Int { get }
      }
      
      protocol IterableIteratorProtocol<Element, Failure>: ~Copyable, ~Escapable {
          associatedtype Element: ~Copyable
          associatedtype Failure: Error = Never
      
          mutating func nextSpan(maximumCount: Int) throws(Failure) -> Span<Element>
        
          mutating func skip(by maximumOffset: Int) throws(Failure) -> Int
      }
    • 27:28 - The problem with existing accessors

      @safe public struct UniqueBox<Value>: ~Copyable {
          private let valuePointer: UnsafeMutablePointer<Value>
      
          public init(_ value: consuming Value) {
              valuePointer = UnsafeMutablePointer.allocate(capacity: 1)
              valuePointer.initialize(to: value)
          }
      
          public var value: Value {
              get { valuePointer.pointee }
              set { valuePointer.pointee = newValue }
          }
      
          deinit {
              valuePointer.deinitialize(count: 1)
              valuePointer.deallocate()
          }
      }
    • 28:19 - 'borrow' and 'mutate' accessors

      @safe public struct UniqueBox<Value: ~Copyable>: ~Copyable {
          private let valuePointer: UnsafeMutablePointer<Value>
      
          public init(_ value: consuming Value) {
              valuePointer = UnsafeMutablePointer.allocate(capacity: 1)
              valuePointer.initialize(to: value)
          }
      
          public var value: Value {
              borrow { valuePointer.pointee }
              mutate { &valuePointer.pointee }
          }
      
          deinit {
              valuePointer.deinitialize(count: 1)
              valuePointer.deallocate()
          }
      }
    • 30:14 - Using 'MutableRef' to eliminate repeated accesses (with un-hoisted access)

      func updateCount<Key: Hashable>(
          for key: Key,
          from sets: [Set<Key>],
          in counts: inout [Key: Int]
      ) {
          for set in sets {
              if set.contains(key) {
                  counts[key, default: 0] += 1
              }
          }
      }
    • 30:34 - Using 'MutableRef' to eliminate repeated accesses (hoisted by 'inout' parameter)

      func updateCount<Key: Hashable>(
          for key: Key,
          from sets: [Set<Key>],
          in counts: inout [Key: Int]
      ) {
          func updateCountImpl(count: inout Int) {
              for set in sets {
                  if set.contains(key) {
                      count += 1
                  }
              }
          }
          
          updateCountImpl(count: &counts[key, default: 0])
      }
    • 30:41 - Using 'MutableRef' to eliminate repeated accesses (hoisted by 'MutableRef')

      func updateCount<Key: Hashable>(
          for key: Key,
          from sets: [Set<Key>],
          in counts: inout [Key: Int]
      ) {
          var countRef = MutableRef(&counts[key, default: 0])
      
          for set in sets {
              if set.contains(key) {
                  countRef.value += 1
              }
          }
      }
    • 0:07 - Introduction
    • A preview of the session's four topics: language improvements, library updates, cross-platform support, and performance tuning in Swift 6.3 and 6.4.

    • 0:44 - Everyday Language Improvements
    • Quality-of-life changes land in Swift 6.4, including optional parentheses removal, concurrency task warnings, weak let, ~Sendable, and a new memberwise initializer.

    • 1:55 - anyAppleOS Availability
    • Swift now lets you condense multi-platform availability attributes into a single anyAppleOS condition, reducing boilerplate across iOS, macOS, watchOS, and more.

    • 3:02 - @diagnose Attribute
    • The new @diagnose attribute gives fine-grained control over warnings within a specific declaration, letting you suppress, enable, or promote them to errors.

    • 3:52 - Module Selectors (::)
    • Swift 6.3 introduces double-colon module selector syntax to unambiguously reference a type or member from a specific module when name conflicts arise.

    • 5:59 - Library Updates
    • Updates across four key libraries: the standard library, Swift Testing, Subprocess, and Foundation.

    • 6:16 - Standard Library
    • New additions include a task cancellation shield, mapKeyedValues for dictionaries, and a cross-platform FilePath type.

    • 7:31 - Swift Testing Updates
    • Swift Testing gains configurable issue severity, dynamic test cancellation, flaky test repetition, and improved two-way interoperability with XCTest.

    • 9:29 - Subprocess 1.0
    • Subprocess reaches 1.0 with a refined API, improved error handling, convenient line-by-line output streaming, and expanded cross-platform support.

    • 10:14 - Foundation
    • Foundation gains a new ProgressManager type and continues its Swift migration, with performance improvements to Data, NSURL, and CFURL.

    • 11:59 - Beyond Apple Platforms
    • Swift 6.4 extends language interoperability and broadens its reach to new environments including web, Android, and embedded devices.

    • 12:35 - Swift–C Interoperability (@C attribute)
    • The new @C attribute lets you expose Swift functions directly to C, enabling safe, incremental migration of C codebases to Swift.

    • 15:09 - Swift-Java
    • The Swift-Java package now supports async and throwing Swift functions from Java, constrained extensions, and conforming Java classes to Swift protocols.

    • 16:03 - Editor support
    • The Swift VSCode extension adds Swiftly integration for toolchain management and is now available on the OpenVSX marketplace for editors like Cursor and VSCodium.

    • 16:44 - WebAssembly (Wasm) & JavascriptKit
    • Swift can now compile to WebAssembly, with JavascriptKit improvements delivering up to 40x faster safe bridging between Swift and JavaScript.

    • 18:08 - Embedded Swift
    • Embedded Swift expands its language subset with existential types, untyped throws, and improved DWARF debug info for coredump debugging on constrained hardware.

    • 19:59 - Performance Tuning
    • Two areas of advanced performance work: explicit optimizer control and extensions to the ownership system to prevent unnecessary copying.

    • 21:29 - Optimizer Control: @inline(always) & @specialized
    • New @inline(always) and @specialized attributes give you direct control over the compiler's inlining and generic specialization decisions.

    • 24:29 - Ownership System & Noncopyable Types
    • Equatable, Comparable, Hashable, and associated types now work with noncopyable and non-escapable types, broadening the ownership system's reach.

    • 26:18 - Iterable Protocol & Borrow/Mutate Accessors
    • A new Iterable protocol enables efficient borrow-based for loops over noncopyable elements, while new borrow and mutate accessors eliminate costly copies in computed properties.

    • 28:57 - New Standard Library Types: UniqueBox, UniqueArray, Ref
    • The standard library gains UniqueBox, UniqueArray, Continuation, and the new Ref/MutableRef types for safe, high-performance ownership patterns.

    • 31:11 - The Future of Swift
    • Highlights open-source progress including Swift Build, new workgroups for build, networking, Windows, and Android, and an invitation to participate at forums.swift.org.

Developer Footer

  • 视频
  • WWDC26
  • Swift 的新功能
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • Apple 智能
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习与 AI
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • Mini Apps Partner Program
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    阅读最近新闻。
    获取 Apple Developer App。
    版权所有 © 2026 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则