Swift guard 语句允许您将可选值解包为一个新常量,并在赋值失败时提前返回。
var someString:String? = "hello"
...
...
guard let newString = someString
else {
return
}
...
如果我想解包一个可选变量并将其设置为预定义的非可选变量,我首先解包为新常量 (newString),然后像这样在 guard 语句之后设置非可选变量:
var someString:String? = "hello"
var nonOptionalString:String = "bonjour"
...
...
guard let newString = someString
else {
return
}
nonOptionalString = newString
...
有没有办法在不创建新常量的情况下在 guard 语句的条件下设置预定义的非可选 var? 像下面这样的东西(不起作用)?
var someString:String? = "hello"
var nonOptionalString:String = "bonjour"
...
...
guard nonOptionalString = someString
else {
return
}
...
如果这样的事情不可能,那么 Swift 语言设计背后是否存在潜在的哲学或技术原因来说明为什么这不存在?
最佳答案
我会测试 nil
,然后在我知道它不是时强制解包:
var someString: String? = "hello"
let nonOptionalString: String // note, you don't have to initialize this with some bogus value
guard someString != nil else { return }
nonOptionalString = someString!
或者如果 someString
是某个方法或闭包的参数,您可以使用相同的变量名在 guard
语句中解包,进一步简化代码:
func foo(someString: String?) {
guard let someString = someString else { return }
// now I can just use local `someString`, which is not optional anymore
}
如果你急于在一条语句中解包并退出-if-nil
,理论上你可以编写一个函数来解包,如果可以的话,或者如果不能则抛出错误:
extension Optional {
enum OptionalError: Error {
case unwrapFailed
}
func unwrap<T>() throws -> T {
if self == nil { throw OptionalError.unwrapFailed }
return self as! T
}
}
然后你可以这样做:
do {
firstNonOptional = try firstOptional.unwrap()
secondNonOptional = try secondOptional.unwrap()
thirdNonOptional = try thirdOptional.unwrap()
} catch {
return
}
我认为这是可怕的矫枉过正,但如果您迫切希望每次解包都将其提炼成一行,这是一种方法。
关于swift - 在不创建新常量的情况下将可选值解包到保护条件中的预定义变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44012462/