我正在尝试x从一个带有f一个参数(字符串)并抛出的函数分配一个值。
当前范围抛出了,所以我相信do... catch不是必需的。
我正在尝试try与合并运算符一起使用,??但出现此错误:'try' cannot appear to the right of a non-assignment operator。
guard let x = try f("a") ??
try f("b") ??
try f("c") else {
print("Couldn't get a valid value for x")
return
}
Run Code Online (Sandbox Code Playgroud)
如果我更改try为try?:
guard let x = try? f("a") ??
try? f("b") ??
try? f("c") else {
print("Couldn't get a valid value for x")
return
}
Run Code Online (Sandbox Code Playgroud)
我得到警告Left side of nil coalescing operator '??' has non-optional type 'String??', so the right side is never used和错误:'try?' cannot appear to the right of a non-assignment operator。
如果我试一试?括号内的:
guard let x = (try? f("a")) ??
(try? f("b")) ??
(try? f("c")) else {
print("Couldn't get a valid value for x")
return
}
Run Code Online (Sandbox Code Playgroud)
它可以编译,但是x是可选的,我希望将其解包。
如果我删除问号:
guard let x = (try f("a")) ??
(try f("b")) ??
(try f("c")) else {
print("Couldn't get a valid value for x")
return
}
Run Code Online (Sandbox Code Playgroud)
我得到了错误Operator can throw but expression is not marked with 'try'。
我正在使用Swift 4.2(在撰写本文时,这是Xcode中的最新版本)。
这样做的正确方法是什么x?
更新:* f()的返回类型为String?。我认为这是一个可选字符串这一事实很重要。
一个try可以覆盖整个表达式,所以你可以说:
guard let x = try f("a") ?? f("b") ?? f("c") else {
print("Couldn't get a valid value for x")
return
}
Run Code Online (Sandbox Code Playgroud)
同样适用于try?:
guard let x = try? f("a") ?? f("b") ?? f("c") else {
print("Couldn't get a valid value for x")
return
}
Run Code Online (Sandbox Code Playgroud)
尽管请注意,在 Swift 4.2x中将是String?由于您正在应用try?一个已经可选的值,为您提供了一个双重包装的可选值,它guard let只会解开一层。
为了解决这个问题,你可以合并到nil:
guard let x = (try? f("a") ?? f("b") ?? f("c")) ?? nil else {
print("Couldn't get a valid value for x")
return
}
Run Code Online (Sandbox Code Playgroud)
但是在 Swift 5 中这是不必要的,因为SE-0230,try? f("a") ?? f("b") ?? f("c")编译器会自动将其中展平为单个可选值。