闽公网安备 35020302035485号
// 1) 显式写 Void
func sayHello() -> Void {
print("Hello World!")
}
// 2) 用空元组 () 代替 Void
func sayHello() -> () {
print("Hello World!")
}
// 3) 直接省略返回箭头与类型(最常见)
func sayHello() {
print("Hello World!")
}
sayHello() // "Hello World!"
.Void 本质是 ()(空元组)的 typealias,所以 -> Void 和 -> () 是一回事。.省略返回箭头是最常见的写法,说明“这个函数只做事,不给结果”。
.文档/教程/示例代码:有时我会刻意写 -> Void 来教学,降低初学者的理解负担。
func process(_ items: [Int]) {
guard !items.isEmpty else { return }
// ... 下面是正式逻辑
}
这里的 return 只是终止,不携带值。let work1: () -> Void = { print("done") }
let work2: () -> () = { print("done") }
let work3: () -> Void in // 不合法,必须写完整
// 正确的第三种:省略整个返回部分
let work3b: () -> Void = { print("done") }
更常见的是带参数、无返回的场景:let transform: (Int) -> Void = { value in
print("value = \(value)")
}
Swift 的类型推断很聪明,但在闭包里省略返回类型容易让签名变得不直观,特别是多层泛型或异步回调时。我的经验是:局部一次性闭包:交给类型推断,代码更短。
func refresh() async {
// 异步刷新,无需返回值
}
Task { await refresh() }
如果你习惯在 Task {} 中写匿名闭包,也可以显式标注它是 () -> Void 的异步版本:@MainActor
func load() async -> Void { // 允许写 -> Void,但多数情况下直接省略
// ...
}
注意:async -> Void 与 async(省略返回)依旧等价;选择哪种仍然是“可读性优先”。enum SaveError: Error { case diskFull }
// 堆代码 duidaima.com
func save(_ data: Data, completion: (Result<Void, SaveError>) -> Void) {
let ok = Bool.random()
if ok { completion(.success(())) } else { completion(.failure(.diskFull)) }
}
这里的 .success(()) 就是把“空元组”作为“成功但无数据”的语义承载体。Alamofire 也常用 Result<Void, Error> 表示“请求成功但无返回体”。func test_save_emitsSuccess() {
let exp = expectation(description: "save success")
save(Data()) { result in
if case .success = result { exp.fulfill() }
}
waitForExpectations(timeout: 1)
}
写在最后