//在guard语句中首先执行let,然后执行bool检查,会导致编译错误
self.action = { [weak self] in
guard let `self` = self, data.isJSON() else { return }
//先执行布尔检查,然后让它工作
self.action = { [weak self] in
guard data.isJSON(), let `self` = self else { return }
上面的两种说法似乎与我的说法相同。为什么在第一种情况下它不起作用?
首先,请注意,如果您的问题包含一个最小、完整且可验证的示例(mvce)就更好了,但在当前形式下,它不包含:
相反,你的问题的mvce可以按照以下方式构建:
func foo(bar: Int?) {
// 1. why does this cause a compile time error?
guard let baz = bar, true else { return }
// 2. whereas this does not?
guard true, let bax = bar else { return }
}
下面的答案将讨论这个mvce,而不是原始问题中模糊的例子。最后还要注意,守卫
/守卫让
语句与问题的核心并不完全相关(唯一),因为我们看到 if
/if let
语句具有相同的行为。下面的答案将使用保护
语句。
上面函数foo(…)
中的第一条保护
statement的编译时错误非常明显
布尔条件需要where
将其与变量绑定分开。
修复此问题:将 替换为
,其中
这在《语言指南-基础知识-可选装订》中也有说明
您可以在单个if
语句中包含多个可选绑定,并使用where
clause检查0.05布尔
条件。如果可选绑定中的任何值为nil
或其中
clause的计算结果为
因此,如果我们想在Guard
或if
语句中的可选绑定之后使用条件子句,则需要使用where
子句将条件子句与前面的可选绑定分开。
func foo(bar: Int?) {
// 1. ok, compiles
guard let baz = bar where true else { return }
/* 2. or, include a conditional-clause prior to the
optional binding, but is this really equivalent..? */
guard true, let bax = bar else { return }
}
然而,这两者并不真正等同;
Guard
语句,以防初始条件子句被证明是false
(然后不进行可选绑定,而是直接进入Guard
语句的else
块)当然,在某些情况下,我们更喜欢一个而不是另一个,例如,如果条件子句包含一些非常繁重的计算,我们可能不想执行这些,除非我们确定可选绑定成功。
let heavyStuff: () -> Bool = { print("foo"); /* ... */ return true }
func foo(bar: Int?) {
/* 1. call the heavyStuff boolean construct only if
the optional binding succeeds */
guard let baz = bar where heavyStuff() else { return }
/* 2. possibly unnesessarily perform heavy boolean
stuff prior to failing the optional binding */
guard heavyStuff(), let bax = bar else { return }
}
一个不太人为的例子是,如果我们想在下面的条件子句中使用一个成功绑定的变量(此处:作为参数)
let integerStuff: (Int) -> Bool = { _ in /* ... */ return true }
func foo(bar: Int?) {
/* 1. call the integerStuff boolean construct only if
the optional binding succeeds, using the binded
immutable as closure argument */
guard let baz = bar where integerStuff(baz) else { return }
/* 2. ... not really any good alternatives for such
flow if using this alternative */
guard integerStuff(baz ?? 0), let bax = bar else { return }
}
最后请注意,从技术上讲,如果您确实想将初始可选绑定与以下条件子句分开,则可以使用虚拟大小写 let
(非可选始终接替变量绑定/赋值)语句以及条件子句的 where
关键字
let checkThis: () -> Bool = { /* ... */ return true }
func foo(bar: Int?) {
// ...
guard let baz = bar, case let _ = () where checkThis() else { return }
}
然而,这只是为了展示这种技术性;在实践中,只需使用where
子句。
我在谷歌分析的实施说明中遇到了这个问题: 我从没想过在 else 子句中有一个断言是可能的,而不返回。这对我来说没有意义,因为断言只会在测试方案中进行评估。那么,为什么编译器不警告它不会返回(在发布版本的情况下)。 编辑:这是在函数
按照下面的介绍youtube.com/playlist?list=plea0wjq13cnafcc0azrcyqucn_tpeljn1创建本体。它稍微缩小了http://prntscr.com/bo4l3w,我自己添加了canBeTutor(意思是某人可以成为某人的导师)对象属性。据我理解,我可以添加SWRL规则,然后启动reasoner来创建新的知识。所以我添加了prntscr.com/bo4l
问题内容: 我知道有些人可能会回答这个问题,但是我的问题来自于您和您的答案。我正在阅读有关SQL注入以及如何保护数据库的过去两个小时的问答。我看到的大量网页和教程也是如此。 我发现有一半人声称prepare语句确实可以保护您的数据库,而另外50人则声称不是。 另一方面,我读到mysql_real_escape_string可以完成这项工作,而其他人则说不行。 我的问题是谁相信? 另外,这是适当的准
问题内容: 我有两个枚举: 如果ServerState设置为基础TL State无法实现的状态,则需要在它们之间进行切换,并返回’false’。例如,如果将返回false 。我试图使用switch语句执行此操作,但是我发现我真正想要的是匹配一个状态 不是 特定状态的情况。例如: 显然,这是行不通的,因为您不能放在case语句之前。我唯一的其他选择是指定所有 允许的 情况,而这种情况要多得多。指定限
我在Jpa存储库中使用Spring Boot。我在循环中保存一些记录,在保存所有记录后,会打印下面的异常。 JAVAsql。SQLRecoverableException:oracle的Instruço Fechada。jdbc。驾驶员OracleClosedStatement。oracle上的getMaxRows(OracleClosedStatement.java:3578)~[ojdbc6-
本文向大家介绍Scala语言保护(if表达式),包括了Scala语言保护(if表达式)的使用技巧和注意事项,需要的朋友参考一下 示例 案例语句可以与if表达式结合使用,以在模式匹配时提供额外的逻辑。 确保您的警卫人员不会产生非详尽的匹配非常重要(编译器通常不会捕获此匹配): 这将引发一个MatchError奇数。您必须考虑所有情况,或使用通配符匹配情况: