为什么guard let foo = foo 无效?

编程入门 行业动态 更新时间:2024-10-27 09:45:44
本文介绍了为什么guard let foo = foo 无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在 Swift 中,您可以使用 if let optional 绑定将一个可选项解包为一个具有相同名称的常量或变量:

In Swift, you can use if let optional binding to unwrap an optional into a constant or variable with the same name:

func test() { let a: Int? = 1 if let a = a { print("a = \(a)") } }

对于 if let 语句中的所有内容,可选的 a 被解包成一个常规的 int.

For everything inside the if let statement, the optional a is unwrapped into a regular int.

同样的,我可以用一个guard语句来达到类似的效果

Likewise, I can use a guard statement to achieve a similar effect

func test() { let a: Int? = 1 guard let requiredA = a else{ return } print("a = \(requiredA)") }

但是,我不能使用这样的代码:guard let a = a else:

However, I can't use code like this: guard let a = a else:

func test() { let a: Int? = 1 guard let a = a else{ return } print("a = \(a)") }

为什么不呢?

在guard语句中,如果guard语句的条件失败,则执行else子句并退出当前作用域.如果条件成功,则从保护语句的右大括号到当前作用域的末尾创建一个新的变量/常量.

In a guard statement, if the conditional of the guard statement fails, the else clause is executed and you exit the current scope. If the conditional succeeds, a new variable/constant is created from guard statement's closing brace to the end of the current scope.

为什么我不能用同样的技巧将一个可选项映射到一个同名的变量/常量中,以用于当前作用域的其余部分?

Why can't I do the same trick of mapping an optional into a variable/constant with the same name for remainder of the current scope?

P.S.:我意识到这个问题不适合这个网站.我愿意接受关于哪里更适合这个问题的建议.

P.S.: I realize this question isn't a perfect fit for this site. I'm open to suggestions as to where would be a better place for this question.

推荐答案

你不能这样做的原因:

func test() { let a: Int? = 1 guard let a = a else{ return } print("a = \(a)") }

是因为 guard 在同一作用域内创建了新变量,因此在同一作用域中有两个名为 a 的变量.一个是Int,另一个是Int?.这是不允许的.

is because guard creates the new variable in the same scope, thus you have two variables called a in the same scope. One is an Int and the other is an Int?. That is not allowed.

您得到的错误定义与以前的值冲突与您执行此操作时完全相同:

The error that you get Definition conflicts with previous value is exactly the same as if you had done this:

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 子句的新作用域中,所以这是有效的.

In this case, the new variable a which is an Int exists only in the new scope of the if's then clause, so this works.

来自评论:

但是我向你提交了右大括号之后的代码段并且到封闭作用域的末尾实际上是一个内部作用域.

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.

我可以理解您希望如此,但事实并非如此.如果是这种情况,那么您可以这样做,但它也会出错:

I can understand that you would like it to be so, but it isn't. If that were the case, then you could do this, but it too gives an error:

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)") }

guard 的美妙之处在于它不会创建新的作用域,并且您可以避免创建重复使用 if let<时导致的死亡金字塔/code> 来解包可选项(并在此过程中创建新的作用域).

The beauty of guard is that it doesn't create new scopes and you avoid creating the pyramid of death that results when you repeatedly use if let to unwrap optionals (and in the process create new scopes).

看后续问题guard let foo = foo 何时变得合法? 以获取有关此主题的更多见解.

See the follow-up question When did guard let foo = foo become legal? for more insight on this topic.

更多推荐

为什么guard let foo = foo 无效?

本文发布于:2023-10-16 15:52:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1498031.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:guard   foo

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!