当前位置: 首页 > 面试题库 >

为什么后卫不让foo = foo有效?

习胤运
2023-03-14
问题内容

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

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

  if let a = a {
    print("a = \(a)")
  } 
}

对于if let语句中的所有内容,可选项都a被包装为常规int。

同样,我可以使用保护语句来达到类似的效果

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

为什么不?

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

为什么我不能做同样的技巧将可选对象映射到具有相同名称的变量/常量,以用于当前作用域的其余部分?

PS: 我知道这个问题并不适合这个网站。对于这个问题在哪里更好,我乐于接受建议。


问题答案:

您无法执行此操作的原因:

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

在这种情况下,新的变量aan Int是仅存在于ifthen子句的新范围内,因此可以正常工作。

从评论:

但是我向您提出,右括号之后到封闭范围的末尾的代码部分实际上是一个内部范围。

我可以理解,您希望这样,但事实并非如此。如果是这种情况,那么您可以执行此操作,但同时也会出现错误:

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



 类似资料:
  • 问题内容: 早在2016年11月,我发布了一个问题,询问为什么我不能使用Guard创建与变量名称相同的未包装版本的变量,就像让let那样: 链接: 为什么后卫不让foo = foo有效? 当我编写该问题时,以下代码将无法编译,并显示“定义与先前值冲突”的错误: 但是,我只是在工作中发现了一些可以做到这一点的代码,现在它可以毫无抱怨地进行编译,并且可以完成我想要的工作!运行时,print语句显示fo

  • 问题内容: 我想知道为什么它是Java不允许超负荷使用,虽然他们都以不同的方式使用? 使用方式如下: 而另一种形式: 使用方式如下: 这背后有什么原因吗? 问题答案: 这个15.12.2.5选择最具体的方法对此进行了讨论,但是它相当复杂。例如,在Foo(数字…整数)和Foo(整数…整数)之间进行选择 为了向后兼容,这些实际上是同一件事。 例如,您可以将main()定义为 一种使它们与众不同的方法是

  • 问题内容: 我看到其他地方说: 等于 我测试了一下,他们确实做了同样的事情。但为什么?到底是什么? 问题答案: AND和OR运算符都可以捷径。 因此,仅在第一个表达式为true时才尝试第二个表达式(更确切地说,是类似事实的表达式)。第二个操作确实起作用(无论其内容如何)的事实无关紧要,因为除非第一个表达式的计算结果为真,否则它不会执行。如果是事实,则将执行它以尝试第二次测试。 相反,如果语句中的第

  • 问题内容: 在Python IDLE 3.5.0 Shell中工作。根据我对内置“过滤器”功能的了解,它会根据您传递给它的内容返回列表,元组或字符串。因此,为什么下面的第一个分配有效,而第二个却不起作用(“ 只是交互式Python提示) 问题答案: 看看python文档(从此处开始): 从这些 iterable 元素构造一个迭代器,为其 功能 返回true。 因此,为了获取列表,您必须使用列表类:

  • 问题内容: 比较这种方法: …对此方法: 对于前一种方法,Eclipse发出警告“不应分配参数’val’”。为什么? 在我看来,前者更清洁。一方面,这并不会迫使我想出 两个 好名字(想出一个好名字已经够难了)。 (注意:假定在封闭的类中没有命名字段。) 问题答案: 看起来好像没有人在这里做过举动。 我通常不会更改参数,实际上,我倾向于标记我的参数以明确禁止使用它。原因如下: 分配参数可能会 与尝试

  • 问题内容: 在Java中,这两个函数声明之间有什么区别? 在这里,您可以找到该问题的答案,但仅适用于 C / C ++ 。在这些语言中,两种声明样式的存在是完全有意义的。 但是在 Java 中这有什么意义呢? 问题答案: 后者在Java中是非法的。您不能声明这样的方法。您应该得到这样的错误: 因此,不仅没有意义-您根本找不到尝试使用此样式的有效代码。