Swift 6.4 新特性

Swift 6.4 内置于 Xcode 27,带来了如下的新特性,使其在安全性、性能与开发体验方面进一步提升。

anyAppleOS

用于一次性覆盖所有 Apple 平台,简化模版代码。

// Swift6.4之前
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
let isApplePlatform = true
#else
let isApplePlatform = false
#endif

@available(macOS 27, iOS 27, watchOS 27, tvOS 27, visionOS 27, *)
func showStatus() {  }

// Swift6.4之后
#if os(anyAppleOS)
let isApplePlatform = true
#else
let isApplePlatform = false
#endif

@available(anyAppleOS 27, *)
func showStatus() {  }

@diagnose

允许在单个声明内改变特定编译器诊断的行为,而不会影响整个项目。

@available(*, deprecated, message: "Use newMethod() instead")
func deprecatedMethod() -> String {
    return "old result"
}

func callDeprecatedMethodOne() -> String {
    deprecatedMethod() // 有警告
}

@diagnose(DeprecatedDeclaration, as: ignored)
func callDeprecatedMethodTwo() -> String {
    deprecatedMethod() // 无警告
}

Dictionary.mapKeyedValues

新增方法,在映射 Value 的同时可以访问对应的 Key 而无需重新构造 Dictionary。

let scores = ["Alice": 90, "Bob": 75, "Carol": 88]

// Swift6.4之前
let oldGrades = Dictionary(
    uniqueKeysWithValues: scores.lazy.map { name, score in
        (name, "\(name): \(score >= 85 ? "优" : "良")")
    }
)

// Swift6.4之后
let grades = scores.mapKeyedValues { name, score in
    "\(name): \(score >= 85 ? "优" : "良")"
}

UniqueArray

新增类型,它是 Array 的不可拷贝(noncopyable)变体,可用于存储不可拷贝元素,同时避免整个容器被隐式复制。

var array = UniqueArray<Int>()
array.append(1)
array.append(2)
array.append(3)
print("UniqueArray count: \(array.count)")

Iterable协议

引入 Iterable 协议,使一些不可拷贝(noncopyable)类型如 Span、InlineArray 也可以直接使用for in遍历,而无需转换为 Array,从而减少不必要的拷贝,提高性能。

var array: InlineArray<5, Int> = [10, 20, 30, 40, 50]

var sum = 0
for value in array {
    sum += value
}
print("Sum: \(sum)")

Memberwise Initializer可访问性改进

当结构体中存在带默认值的private属性时,编译器会同时生成两个成员逐一初始化方法:包含全部属性的private版(内部使用)以及排除该属性、保持更高的可访问性版(外部调用),避免private默认值属性影响初始化方法的可访问性。

import Foundation

struct Person {
    var name: String
    var birthday: Date
    private var hobbies: [String] = []  // private+有初始值
}

// Swift6.4之前:编译器仅生成 private init(name:birthday:hobbies:)
// Swift6.4之后:编译器同时生成 
    // private init(name:birthday:hobbies:)
    // internal init(name:birthday:),hobbies 自动使用默认值

let person = Person(name: "ZhangSan", birthday: Date())
print("Name: \(person.name)")
print("Birthday: \(person.birthday)")

FilePath

FilePath 正式成为 Swift 标准库的一部分,提供跨平台的文件路径类型,支持路径组件级别的操作与拼接。

var path: FilePath = "/Users/yangfan/Desktop/Website"

// 追加路径组件
path.components.append("WWDC26")
print(path)

// 查看路径组件(不含根目录)
print(path.components.map(\.string))

// 路径拼接(非变异方式)
let logPath = FilePath("/Users/yangfan/Desktop").appending("app.log")
print(logPath)

并发编程

  1. 允许在defer代码块中使用异步操作。
func cleanup() async {
    print("File closed")
}

func processFile() async throws {
    print("Open file")

    defer {
        // Swift6.4之后
        await cleanup()
    }

    print("Processing...")
    
    // 模拟异步工作
    try await Task.sleep(for: .milliseconds(100))
    
    print("Finish Processing file")
}

Task {
    do {
        try await processFile()
    } catch {
        print("Error: \(error)")
    }
}
  1. 新增withTaskCancellationShield,在关键代码执行期间暂时屏蔽任务取消,确保关键操作能够完整执行。
func doSomething() async {
    let task = Task {
        // 保护关键操作不被取消中断
        await withTaskCancellationShield {
            // 模拟关键操作
            print("Start critical work")

            try? await Task.sleep(for: .seconds(2))
            
            print("Critical work finished")
        }
    }

    task.cancel() // 即使取消,withTaskCancellationShield中的代码依然执行
    await task.value
}

Task {
    await doSomething()
}
  1. 新增~Sendable语法,显式声明一个类型不满足 Sendable。
func sendToActor<T: Sendable>(_ value: T) {
    print("Sent: \(value)")
}

struct Person: Sendable {
    var name: String
}

struct Student: ~Sendable {
    var age: Int
}

sendToActor(Person(name: "ZhangSan"))
// 报错:Type 'Student' does not conform to the 'Sendable' protocol
sendToActor(Student(age: 20))
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容