当前位置: 首页 > 知识库问答 >
问题:

Swift的guard关键字

徐智渊
2023-03-14

Swift 2 引入了 guard 关键字,该关键字可用于确保各种数据已配置就绪。我在这个网站上看到的一个例子演示了一个提交已开发的功能:

func submitTapped() {
    guard username.text.characters.count > 0 else {
        return
    }

    print("All good")
}

我想知道使用< code>guard与使用< code>if条件的老式方法有什么不同。它能给你带来用简单的支票无法得到的好处吗?

共有3个答案

丁雅懿
2023-03-14

guard确实有两大好处。一个是避免末日金字塔,正如其他人所提到的那样——如果让语句嵌套在一起,那么会有很多恼人的语句不断向右移动。

另一个好处通常是你想要实现的逻辑更像是“如果不是让”而不是“如果让{}else”。

这是一个示例:假设您想实现累积-mapduce之间的交叉,它会返回一个正在运行的减少数组。这是与Guard一起:

extension Sliceable where SubSlice.Generator.Element == Generator.Element {

    func accumulate(combine: (Generator.Element,Generator.Element)->Generator.Element) -> [Generator.Element] {
        // if there are no elements, I just want to bail out and
        // return an empty array
        guard var running = self.first else { return [] }

        // running will now be an unwrapped non-optional
        var result = [running]

        // dropFirst is safe because the collection
        // must have at least one element at this point
        for x in dropFirst(self) {
            running = combine(running, x)
            result.append(running)
        }
        return result
    }

}


let a = [1,2,3].accumulate(+)  // [1,3,6]
let b = [Int]().accumulate(+)  // []

你会如何在没有保护的情况下编写它,但仍然使用首先返回可选选项?像这样:

extension Sliceable where SubSlice.Generator.Element == Generator.Element {

    func accumulate(combine: (Generator.Element,Generator.Element)->Generator.Element) -> [Generator.Element] {

        if var running = self.first  {
            var result = [running]

            for x in dropFirst(self) {
                running = combine(running, x)
                result.append(running)
            }
            return result
        }
        else {
            return []
        }
    }

}

额外的嵌套很烦人,但是,将ifelse相距如此之远也不符合逻辑。为空大小写提前退出更具可读性,然后继续处理函数的其余部分,就好像这是不可能的一样。

潘雅珺
2023-03-14

if不同,Guard创建可以从其块外部访问的变量。打开许多可选很有用。

萧萧迟
2023-03-14

阅读这篇文章时,我注意到了使用Guard的巨大好处

在这里,您可以将警卫的使用与示例进行比较:

这是没有防护装置的部件:

func fooBinding(x: Int?) {
    if let x = x where x > 0 {
        // Do stuff with x
        x.description
    }

    // Value requirements not met, do something
}

> < li>

在这里,您将所需的代码放入所有条件中

您可能不会立即看到这方面的问题,但您可以想象,如果它嵌套了许多在运行语句之前需要满足的条件,它会变得多么混乱

清理这个问题的方法是先做每一个检查,如果不满足任何检查,就退出。这可以很容易地理解什么条件会使这个函数退出。

但现在我们可以使用后卫,我们可以看到这可以解决一些问题:

func fooGuard(x: Int?) {
    guard let x = x where x > 0 else {
        // Value requirements not met, do something
        return
    }

    // Do stuff with x
    x.description
}
  1. 检查你想要的条件,而不是你不想要的条件。这同样类似于断言。如果不满足条件,则运行guard的else语句,这将中断函数
  2. 如果条件通过,这里的可选变量将在调用guard语句的范围内自动展开,在本例中是fooGuard(_:)函数
  3. 您正在尽早检查坏案例,使您的函数更具可读性,更易于维护

同样的模式也适用于非可选值:

func fooNonOptionalGood(x: Int) {
    guard x > 0 else {
        // Value requirements not met, do something
        return
    }

    // Do stuff with x
}

func fooNonOptionalBad(x: Int) {
    if x <= 0 {
        // Value requirements not met, do something
        return
    }

    // Do stuff with x
}

如果您仍然有任何疑问,可以阅读整篇文章:Swift警卫声明。

总结

最后,通过阅读和测试,我发现如果你用保镖打开任何可选包装,

这些未包装的值会保留下来,供您在代码块的其余部分中使用

.

guard let unwrappedName = userName else {
    return
}

print("Your username is \(unwrappedName)")

此处,未包装的值仅在if块内可用

if let unwrappedName = userName {
    print("Your username is \(unwrappedName)")
} else {
    return
}

// this won't work – unwrappedName doesn't exist here!
print("Your username is \(unwrappedName)")
 类似资料:
  • 根据我对声明的理解,我正在做以下工作: 我只想了解一下,我们是否可以在 语句中创建一个变量,并在函数的其余部分访问它?或者保护语句是否旨在立即返回或引发异常? 还是我完全误解了声明的用法?

  • 问题内容: 我正在尝试从parse.com实现一些代码,并且在void后发现一个关键字。 我难住了,这是什么?您在第二行看到 该文档没有对此进行说明。我知道关键字用于循环。 有人确认吗? 问题答案: 在命名函数中,我们声明参数并在声明行中返回类型。 在匿名函数中,没有声明行-它是匿名的!因此,我们在正文的开头使用一行来代替。 (这是匿名函数的 完整 形式。但是Swift拥有一系列规则,允许在某些情

  • 我试图在一个保护语句中调用一个名为“nextPage”的函数,但它说“()”不能转换为“Bool”。要调用此函数,我需要做什么

  • 问题内容: 来自标准库的文件包含围绕228行的以下几行代码: 在这种情况下是什么意思,或者通常是什么关键字? 问题答案: 是Swift 3中的新访问级别,随实现而引入 SE-0117允许区分公共访问权限和公共替代权限 从2016年8月7日开始,Swift 3快照和Xcode 8 beta 6都可以使用它。 简而言之: 在定义模块之外, 可以访问 和 可继承 一个类。一类成员是 可访问 和 可重写

  • 问题内容: 我正在使用[UIImage:UIImage]类型的快速字典,并且正在尝试查找给定值的特定键。在Objective- C中,我可以使用allKeysForValue,但是Swift字典似乎没有这种方法。我应该使用什么? 问题答案: Swift 3:针对双射字典的特殊情况,性能更高 如果反向字典查找用例涵盖了在键和值之间具有一对一关系的双射字典,那么穷举收集操作的另一种方法是使用更快的短路

  • 问题内容: 当读取a的初始化程序时,我看到一些参数默认为value 。什么是关键词代表什么? 问题答案: 这不是有效的Swift代码,它是即时生成的。 在这里意味着有一些默认值,但发电机不能想像它适合你才能看到它。从技术上来说,默认值是一个内联函数,因此不能轻易将其转换为简单的声明。 您可以看到类似的声明 其中默认为(在Swift 1.x中)和默认为(在Swift 1.x中)。 在的情况下,默认值