gpt4 book ai didi

swift - 为什么 guard let foo = foo 无效?

转载 作者:搜寻专家 更新时间:2023-10-30 22:29:30 24 4
gpt4 key购买 nike

在 Swift 中,你可以使用 if let optional binding 来将一个 optional 解包为一个同名的常量或变量:

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 语句的右大括号到当前范围的末尾创建一个新的变量/常量。

为什么我不能在当前范围的其余部分使用相同的技巧将可选映射到具有相同名称的变量/常量?

附注:我意识到这个问题不适合这个网站。我愿意听取关于在哪里更适合回答这个问题的建议。

最佳答案

你不能这样做的原因:

func test()
{
let a: Int? = 1

guard let a = a else{
return
}
print("a = \(a)")
}

是因为 guard 在同一范围内创建了新变量,因此在同一范围内有两个名为 a 的变量。一个是 Int,另一个是 Int?。这是不允许的。

您得到的错误Definition conflicts with previous value 与您执行此操作完全相同:

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

guard 的美妙之处在于它不会创建新的作用域,并且您可以避免创建死亡金字塔,这种情况在您重复使用 if let< 时会产生 解包选项(并在此过程中创建新的范围)。


见后续问题 When did guard let foo = foo become legal?了解有关此主题的更多信息。

关于swift - 为什么 guard let foo = foo 无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40353631/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com