swift – 为什么不守卫让foo = foo有效?

在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.:我意识到这个问题不适合这个网站.我愿意接受有关这个问题哪个地方更好的建议.

你不能这样做的原因:
func 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?有关此主题的更多见解.

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...