ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SE-0530] Async Result Support
    Swift 2026. 6. 7. 15:09

    안녕하세요. 그린입니다 🍏

    이번 포스팅에서는 SE-0530 — Result 타입의 async 이니셜라이저 추가에 대해 정리해보겠습니다 🙋🏻


    Intro

    • Proposal: SE-0530
    • Authors: Konrad 'ktoso' Malawski, Matt Massicotte
    • Review Manager: Doug Gregor
    • Status: Implemented (Swift 6.4)

    Motivation

    Swift의 Result 타입은 throwing 코드를 다룰 때 굉장히 유용한 도구입니다.

    기존의 Result.init(catching:)은 throwing 클로저를 Result 인스턴스로 변환해주는 편리한 이니셜라이저예요.

    // 기존: 동기 버전은 있음
    let result = Result { try syncWork() }

    그런데 async 버전이 없었어요. 비동기 작업에서 동일한 패턴을 쓰려면 매번 직접 구현해야 했거든요.

     

    // 지금까지의 불편한 방식 — 코드베이스마다 중복 구현
    let result: Result<Data, any Error>
    do {
      result = .success(try await asyncWork())
    } catch {
      result = .failure(error)
    }

    어렵진 않지만, 유용성 때문에 많은 코드베이스에서 수동으로 중복 구현되고 있었거든요. 표준 라이브러리가 제공해야 마땅한 패턴이에요!


    Proposed Solution

    Result.init(catching:)async 오버로드를 추가합니다.

    이를 통해 아래처럼 간결하게 쓸 수 있게 됩니다.

    let result = await Result {
      try await asyncWork()
    }

     


    Detailed Design

    제안하는 API 변경 사항은 다음과 같습니다.

    extension Result where Success: ~Copyable {
      /// Creates a new result by evaluating a throwing closure,
      /// capturing the returned value as a success,
      /// or any thrown error as a failure.
      ///
      /// - Parameter body: A potentially throwing asynchronous closure to evaluate.
      @_alwaysEmitIntoClient
      public nonisolated(nonsending) init(
        catching body: nonisolated(nonsending) () async throws(Failure) -> Success
      ) async {
        do {
          self = .success(try await body())
        } catch {
          self = .failure(error)
        }
      }
    }
    주요 포인트를 살펴볼게요~!

    • Success: ~Copyable — noncopyable 타입도 Success로 사용할 수 있습니다.
    • throws(Failure) — SE-0413의 typed throws를 활용해 Failure 타입을 정확하게 표현합니다.
    • nonisolated(nonsending) — actor isolation 없이 호출 가능하며, 클로저의 반환값을 안전하게 전달합니다.
    • @_alwaysEmitIntoClient — 이니셜라이저가 클라이언트 바이너리에 직접 인라인되어 backdeployment가 가능합니다.

    Source Compatibility / ABI

    • 이번 변경은 순수 additive 변경으로, 기존 코드에 영향을 주지 않습니다.
    • @_alwaysEmitIntoClient로 표시되어 이전 Swift 버전으로의 backdeployment가 가능합니다.

    Conclusion

    아주 작은 변경이지만, 비동기 코드에서 Result를 다루는 패턴이 훨씬 간결해집니다 🙌

    많은 코드베이스에서 반복적으로 직접 구현해왔던 보일러플레이트를 표준 라이브러리가 흡수해주는 변경이에요.

    Result { try await asyncWork() } — 동기 버전과 완전히 동일한 패턴으로 async 작업을 처리할 수 있게 되어, 코드의 일관성도 높아질 것 같습니다 😄


    References

     

    swift-evolution/proposals/0530-async-result-support.md at main · swiftlang/swift-evolution

    This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swiftlang/swift-evolution

    github.com

     

Designed by Tistory.