使用 "where" 子句在 Swift 算术中生成可选类型
Using "where" clauses to produce optional types in Swift arithmetic
我想在用户交互期间触发基于某些 UI 关系的条件逻辑(在这种情况下,我想在用户滚动到 UIScrollView
中的某个点时调用一个方法).我希望以下代码行能够合法地执行此操作,因为它非常具有表现力:
func scrollViewDidScroll(scrollView: UIScrollView) {
guard let overlap = scrollView.contentOffset.y - 220 where overlap > 0 else {
return
}
reactToScrollOverlap(of: overlap)
}
但是,我收到 guard let
需要可选类型的错误。这是合理的,但我预计在这种情况下 where
子句自然会引入一个可选的,因为如果算术运算错误那么就不存在 overlap
.
的匹配值
有没有一种方法可以使用 guard let
(或者,if let
),这样包含的 where
子句就 Int、CGFloat 或其他算法之间的算术结果规定了条件primitive/primitive-like 类型?
guard
和 if let
语句通常只用于解包可选值。我对这个解决方案不是很满意,但您可以将 scrollView.contentOffset.y
转换为 Optional<CGFloat>
以获得您想要的行为:
guard let overlap = scrollView.contentOffset.y - 220 as CGFloat? where overlap > 0 else {
return
}
guard let value = someOptionalValue {
}
if let value = someOptionalValue {
}
这些是将可选值绑定到变量的方式。如果您使用的是 guard let
或 if let
,则您使用的是仅从可选类型获取值。
只有当所有可选值都在 where 子句之前有一个值时,where 子句才会被触发。
我想你想做的是这样的:
let delta = scrollView.contentOffset.y - 220
if delta > 0 {
} else {
}
我更喜欢清晰而不是简洁。
编辑:
我认为这是一个更好的方法:
let yOffset = scrollView.contentOffset.y
let newOffset:Int? = yOffset > 220 ? yOffset : nil
您在一个表达式中做了 3 件事 - 声明一个变量(常量)、分配它并检查它的值。
在表达式中声明一个变量通常是不受欢迎的,Swift 并没有真正启用它。除了一个例外 - 可选项的展开。您没有解包一个可选的,所以只需将表达式正确地拆分为一个声明和一个比较:
let overlap = contentOffset.y - 220
guard overlap > 0 else {
return
}
另一种选择是使用 case let
模式。我不是它的忠实粉丝,但它可能是你想要的:
guard case let overlap = contentOffset.y - 220 where overlap > 0 else {
return
}
print("overlap:", overlap)
我想在用户交互期间触发基于某些 UI 关系的条件逻辑(在这种情况下,我想在用户滚动到 UIScrollView
中的某个点时调用一个方法).我希望以下代码行能够合法地执行此操作,因为它非常具有表现力:
func scrollViewDidScroll(scrollView: UIScrollView) {
guard let overlap = scrollView.contentOffset.y - 220 where overlap > 0 else {
return
}
reactToScrollOverlap(of: overlap)
}
但是,我收到 guard let
需要可选类型的错误。这是合理的,但我预计在这种情况下 where
子句自然会引入一个可选的,因为如果算术运算错误那么就不存在 overlap
.
有没有一种方法可以使用 guard let
(或者,if let
),这样包含的 where
子句就 Int、CGFloat 或其他算法之间的算术结果规定了条件primitive/primitive-like 类型?
guard
和 if let
语句通常只用于解包可选值。我对这个解决方案不是很满意,但您可以将 scrollView.contentOffset.y
转换为 Optional<CGFloat>
以获得您想要的行为:
guard let overlap = scrollView.contentOffset.y - 220 as CGFloat? where overlap > 0 else {
return
}
guard let value = someOptionalValue {
}
if let value = someOptionalValue {
}
这些是将可选值绑定到变量的方式。如果您使用的是 guard let
或 if let
,则您使用的是仅从可选类型获取值。
只有当所有可选值都在 where 子句之前有一个值时,where 子句才会被触发。
我想你想做的是这样的:
let delta = scrollView.contentOffset.y - 220
if delta > 0 {
} else {
}
我更喜欢清晰而不是简洁。
编辑:
我认为这是一个更好的方法:
let yOffset = scrollView.contentOffset.y
let newOffset:Int? = yOffset > 220 ? yOffset : nil
您在一个表达式中做了 3 件事 - 声明一个变量(常量)、分配它并检查它的值。
在表达式中声明一个变量通常是不受欢迎的,Swift 并没有真正启用它。除了一个例外 - 可选项的展开。您没有解包一个可选的,所以只需将表达式正确地拆分为一个声明和一个比较:
let overlap = contentOffset.y - 220
guard overlap > 0 else {
return
}
另一种选择是使用 case let
模式。我不是它的忠实粉丝,但它可能是你想要的:
guard case let overlap = contentOffset.y - 220 where overlap > 0 else {
return
}
print("overlap:", overlap)