【问题标题】:Swift 5.5 Concurrency: creating a task with custom error typeSwift 5.5 并发:创建具有自定义错误类型的任务
【发布时间】:2021-10-19 08:40:21
【问题描述】:

我需要在我创建的任务中使用我自己的自定义错误枚举:

enum MyError: Error {
 case someError
}

var myTask: Task<MyModel, MyError> = Task { () throws -> MyModel in
            // in case of an error: 
            // throw .someError
            // ... perform some work
            return MyModel()
        }

但我在任务初始化程序的开头收到以下错误: Referencing initializer 'init(priority:operation:)' on 'Task' requires the types 'MyError' and 'Error' be equivalent.

如何限制Task 仅抛出属于我的自定义错误类型MyError 的错误?

【问题讨论】:

  • 为什么首先要声明类型为Task&lt;MyModel, MyError&gt;
  • 试图告诉编译器我需要使用MyError
  • 您并没有完全理解我的要求。没有什么能阻止您声明 Task&lt;MyModel, Error&gt; 或完全忽略声明的事件。你可以扔任何你想扔的东西。
  • 我需要声明Task&lt;MyModel, MyError&gt; 而不是Task&lt;MyModel, Error&gt;
  • 不,你“不需要”。你想要。有很大的不同。

标签: swift xcode13 swift5.5 swift-concurrency


【解决方案1】:

省略不必要的类型声明:

var myTask = Task { () throws -> MyModel in
    // in case of an error:
    throw MyError.someError
    // ... perform some work
    return MyModel()
}

编译器隐式(并且正确地)将myTask 类型为Task&lt;MyModel, Error&gt;。编译器不在乎你抛出的是 MyError,因为那是 Error 的一种形式。


好的,我现在看到问题仅仅是您问错了问题。您想知道为什么您不能将此任务声明为Task&lt;MyModel,MyError&gt;

原因在于这个初始化器是如何声明的:

extension Task where Failure == Error {
    public init(priority: TaskPriority? = nil, operation: @escaping @Sendable () async throws -> Success)
}

你看到了吗?此初始化程序仅在 where Failure == Error 可用。那是==,而不是:。使用这个初始化器不需要Failure类型是an Error,它需要 Error。

【讨论】:

  • 我知道我可以这样使用它,但是我的应用程序中的错误枚举以及创建的任务很多,我需要一种方法来静态告诉编译器特定任务应该只抛出 @ 987654329@,但不是任何其他类型的Error
  • 如果你知道答案,为什么还要问这个问题?
  • 好的,等等,我看到了问题:你问错了问题。我会回答你应该提出的问题。
  • 好吧,至于“我怎样才能限制任务只抛出我的自定义错误类型 MyError 的错误”,你不能。但这不足为奇。一个普通的throws 函数声明不能​​指定它抛出什么类型的东西。
  • 您当然可以编写强制自己仅发出 MyError 错误的代码!如果您的问题是如何做到这一点,请提出一个新问题。但关键是,您不能使用 Task 通用失败类型作为您的方式。如果您认为这是错误的,请向 Apple 提交错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-04
相关资源
最近更新 更多