在不创建新常量的情况下将可选值解包到保护条件中的预定义变量
Unwrapping optionals to a pre-defined variable in the guard condition without creating a new constant
Swift guard 语句允许您将可选值解包为一个新常量,并在赋值失败时尽早 return。
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 语言设计或技术原因背后是否存在关于为什么这不存在的基本哲学?
如果重点是只在赋值可能的情况下进行赋值,写:
nonOptionalString = someString ?? nonOptionalString
如果你真的也需要return
如果赋值是不可能的,那么就写一个if/else子句:
if someString != nil {
nonOptionalString = someString!
} else {
return
}
换句话说,别再花哨了,说出你的意思。
我有两种方法可以做到这一点。
guard let someString = someString else { return }
这只是检查具有相同变量名称的值。
guard someString != nil else { return }
做第二个,你甚至可以用一声巨响 (!) 声明它在某种程度上是 "pre-defined" 到 "non-optional"。
所以现在你可以像这样声明它:
var someString:String! = "hello"
我想你正在寻找这个。
编辑:现在您可以使用自己的示例了。
guard someString != nil, nonOptional == someString else { return }
我只会测试 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 guard 语句允许您将可选值解包为一个新常量,并在赋值失败时尽早 return。
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 语言设计或技术原因背后是否存在关于为什么这不存在的基本哲学?
如果重点是只在赋值可能的情况下进行赋值,写:
nonOptionalString = someString ?? nonOptionalString
如果你真的也需要return
如果赋值是不可能的,那么就写一个if/else子句:
if someString != nil {
nonOptionalString = someString!
} else {
return
}
换句话说,别再花哨了,说出你的意思。
我有两种方法可以做到这一点。
guard let someString = someString else { return }
这只是检查具有相同变量名称的值。
guard someString != nil else { return }
做第二个,你甚至可以用一声巨响 (!) 声明它在某种程度上是 "pre-defined" 到 "non-optional"。
所以现在你可以像这样声明它:
var someString:String! = "hello"
我想你正在寻找这个。
编辑:现在您可以使用自己的示例了。
guard someString != nil, nonOptional == someString else { return }
我只会测试 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
}
我认为这是可怕的矫枉过正,但如果您迫切希望每次展开都将其提炼成一行,这是一种方法。