在Swift中,您可以使用if allow可选绑定将可选项解包为具有相同名称的常量或变量:
func test() { let a: Int? = 1 if let a = a { print("a = \(a)") } }
对于if let语句中的所有内容,可选的a将被解包为常规int.
同样,我可以使用guard语句来实现类似的效果
func test() { let a: Int? = 1 guard let requiredA = a else{ return } print("a = \(requiredA)") }
但是,我不能使用这样的代码:guard let a = a else:
func test() { let a: Int? = 1 guard let a = a else{ return } print("a = \(a)") }
为什么不?
在guard语句中,如果guard语句的条件失败,则执行else子句并退出当前作用域.如果条件成功,则会从guard语句的右括号创建一个新的变量/常量到当前作用域的末尾.
为什么我不能将可选项映射到当前作用域的其余部分的同名变量/常量?
P.S.:我意识到这个问题不适合这个网站.我愿意接受有关这个问题哪个地方更好的建议.
你不能这样做的原因:
原文链接:https://www.f2er.com/swift/320125.htmlfunc test() { let a: Int? = 1 guard let a = a else{ return } print("a = \(a)") }
是因为guard在同一范围内创建了新变量,因此在同一范围内有两个名为a的变量.一个是Int,另一个是Int?.这是不允许的.
您获得的定义与先前值冲突的错误与您执行此操作时完全相同:
func test() { let a: Int? = 1 let a = a! }
与之相比:
func test() { let a: Int? = 1 if let a = a { print("a = \(a)") } }
在这种情况下,作为Int的新变量a仅存在于if的then子句的新范围中,因此这是有效的.
来自评论:
But I submit to you that the section of code after the closing brace
and to the end of the enclosing scope is actually an inner scope.
我可以理解你希望它是这样,但事实并非如此.如果是这种情况,那么你可以这样做,但它也会出错:
func test() { let a: Int? = 1 guard let b = a else{ return } print("b = \(b)") let a = 5 // Definition conflicts with prevIoUs value print("a = \(a)") }
守卫的美妙之处在于,它不会创建新的范围,并且您可以避免在重复使用时创建死亡金字塔,如果让我们打开选项(并在此过程中创建新的范围).
请参阅后续问题
When did guard let foo = foo become legal?有关此主题的更多见解.