swift – 什么时候`守卫让foo = foo`变得合法?

回到2016年11月,我发布了一个问题,询问为什么我不能使用guard来创建一个使用与可选项相同名称的变量的解包版本,就像你可以使用if:

链接Why isn’t guard let foo = foo valid?

当我写下这个问题时,下面的代码将无法编译,并出现“定义与先前值冲突”的错误

//Test of using guard to create an unwrapped version of a var,like if let
func guardTest(_ viewController: UIViewController?) -> UIViewController? {
  // Check if the current viewController exists
  print(String(describing: viewController))
  guard let viewController = viewController else {
    return nil
  }
  print(String(describing: viewController))

  return viewController
}

但是,我刚刚在工作中发现了一些代码,它现在可以编译而无需投诉,并按照我的意愿行事!运行时,print语句显示foo在guard之前是可选的,而在以下之后是一个unwrapped可选:

viewController = Optional(<TrochoidDemo.ViewController: 0x7ff16a039a00>)
viewController = <TrochoidDemo.ViewController: 0x7ff16a039a00>

(如果你想尝试一下,我将测试函数guardTest(_ :)添加到我最新的开源项目中.它可以在Github上获得,时间是https://github.com/DuncanMC/TrochoidDemo)

我很高兴这个结构现在可以按照我的意愿运行,但是为什么它现在合法,以及何时发生变化感到困惑.

是否有人知道最近对语言定义的更改使得此构造工作在之前没有的地方?

TL; DR

如果foo是在另一个范围内定义的,那么让foo = foo是合法的.

链接问题的示例:

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

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

仍然不起作用,因为guard语句试图在同一范围内创建另一个变量a.

这个例子:

//Test of using guard to create an unwrapped version of a var,like if let
func guardTest(_ viewController: UIViewController?) -> UIViewController? {
  // Check if the current viewController exists
  print(String(describing: viewController))
  guard let viewController = viewController else {
    return nil
  }
  print(String(describing: viewController))

  return viewController
}

这与以下原因相同:

func test(a: Int)
{
    print(type(of: a))  // Int

    let a = 3.14

    print(type(of: a))  // Double
}

函数的参数在不同的范围内定义,因此Swift允许您创建具有相同名称的局部变量.

相关文章

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