它有时有效,但有些抛出错误:无法推断通用参数'T' - Swift
Posted
技术标签:
【中文标题】它有时有效,但有些抛出错误:无法推断通用参数\'T\' - Swift【英文标题】:It works sometimes, but some throws error: Generic parameter 'T' could not be inferred - Swift它有时有效,但有些抛出错误:无法推断通用参数'T' - Swift 【发布时间】:2021-12-25 17:15:18 【问题描述】:直到现在我都没有遇到任何问题,这很奇怪。 Swift 从未抱怨过这段代码。一个用户注册时出错,我调试了一个打印语句,也许是因为代码的自省,现在 swift 捕获了错误并说:
Generic parameter 'T' could not be inferred
我认为这就是您处理延续的方式,我的代码有什么问题? 有趣的是它有时会起作用,有时会抛出上面的错误:/
错误在一行:try await withCheckedThrowingContinuation
这是完整的代码:
// Signup
final func signUp(username: String, email: String, password: String) async throws -> (message: String, didItSucceed: Bool)
print("➡️ About to sign up user")
try await withCheckedThrowingContinuation continuation in
let userAttributes = [AuthUserAttribute(.email, value: email)]
let options = AuthSignUpRequest.Options(userAttributes: userAttributes)
_ = Amplify.Auth.signUp(
username: username,
password: password,
options: options
) result in
switch result
case .success(let signUpResult):
print("✅ Signup confirmed. Next-> needs email verification from \(email)")
switch signUpResult.nextStep
case .done:
print("✅ Finished sign up!")
case .confirmUser(_, _):
DispatchQueue.main.async
// Confirm the Auth State to confirm code passing in the username to confirm
self.authState = .login
continuation.resume(returning: ("Check your Email ????", true))
case .failure(let error):
var errorMessageToTheUser = "Something went wrong ????"
print(error)
continuation.resume(returning: (errorMessageToTheUser, false))
编辑:
如果我删除 withCheckedThrowingContinuation
顶部的 print(),异常就会消失。但是用户注册时的错误仍然存在,并且在行崩溃:
try await withCheckedThrowingContinuation continuation in
并将(错误)带到@main struct
说:线程1:EXC_BAD_ACCESS (code=1, address=0x46b56a8a6b20)
怎么了?
【问题讨论】:
【参考方案1】:首先,您应该使用withUnsafeThrowingContinuation
。 Checked
版本仅用于测试您是否正确执行了所有操作;它有你不想遇到的开销,除非你必须这样做。 (但是,正如我们将看到的,您并没有正确地做所有事情,所以这实际上是目前的一个不错的选择!)
其次,如果您查看文档,您会发现这是一个泛型函数,其类型 T 是通过 CheckedContinuation(您的 continuation
)的解析来解决的。所以不要仅仅说
continuation in
如有必要,您可以提供类型信息:
(continuation: CheckedContinuation<WhatType, Error>) -> Void in
(我不知道你应该为 WhatType 输入什么类型,因为你没有提供足够的信息。)
第三,您正在崩溃,因为您错误地使用了延续。您必须在实现中每个可能的退出路径上准确调用一次continuation.resume
,而您没有这样做(例如查看.done
路径)。我想你会发现,当你解决了这个问题后,其他问题就会迎刃而解。
第四,print
语句改变一切的原因是,在你把它放在那里之前,在你的try await
之前有一个隐含的return
。多亏了这一点,编译器才能够推断出有问题的类型。但是,当您添加 print
时,您将其取消了。如果您输入return try await
,您的编译问题可能会全部消失(尽管您仍然会崩溃,因为您没有正确使用延续)。
【讨论】:
现在正在读取您的 cmets,我返回的类型在函数上,它将是 (String, Bool) 有趣的是,我很久以前在使用延续时问过,他们告诉我相反,我不应该使用withUnsafeThrowingContinuation
。我将如何返回字符串和布尔值?我试过这个:try await withUnsafeThrowingContinuation (continuation: CheckedContinuation<String, Bool, Error>) ->
但不起作用。
好吧,有了你的 cmets,我有点想这就是我让它工作的方式,请检查它是否正确:return try await withUnsafeThrowingContinuation (continuation: UnsafeContinuation<(message: String, didItSucceed: Bool), Error>) -> Void in
编辑:不断抛出错误:/
你打败了我!很好,但在这样做之前我会三思而后行。请记住,throws
的全部意义在于您通过投掷来表示失败。不需要返回 String-and-a-Bool。要么你返回一个字符串,要么你抛出。所以我会说重新考虑你在这个方法上的整个架构。
它仍然抛出错误:/以上是关于它有时有效,但有些抛出错误:无法推断通用参数'T' - Swift的主要内容,如果未能解决你的问题,请参考以下文章