我正在尝试从函数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
}
如果我将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
}
我收到警告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
}
它可以编译,但是x是可选的,我希望将其解包。
如果我删除问号:
guard let x = (try f("a")) ??
(try f("b")) ??
(try f("c")) else {
print("Couldn't get a valid value for x")
return
}
我收到错误Operator can throw but expression is not marked with 'try'
。
我正在使用Swift 4.2(在撰写本文时,这是Xcode中的最新版本)。
在x
中获取未包装值的正确方法是什么?
更新:* :f()
的返回类型为String?。我认为这是一个可选字符串这一事实很重要。
答案 0 :(得分:4)
单个try
可以覆盖整个表达式,因此您可以说:
guard let x = try f("a") ?? f("b") ?? f("c") else {
print("Couldn't get a valid value for x")
return
}
try?
也一样:
guard let x = try? f("a") ?? f("b") ?? f("c") else {
print("Couldn't get a valid value for x")
return
}
尽管请注意,在Swift 4.2中,x
将是String?
,这是因为您正在将try?
应用于一个已经可选的值,从而为您提供了一个双重包装的可选选项,其中{ {1}}只会解开一层。
要解决此问题,您可以合并为guard let
:
nil
但是在Swift 5中,由于SE-0230,这是不必要的, guard let x = (try? f("a") ?? f("b") ?? f("c")) ?? nil else {
print("Couldn't get a valid value for x")
return
}
将由编译器自动展平为单个可选值。