Swift 无法在循环中推断条件类型
Swift can't infer conditional type in a loop
当我使用 case let
投射视图时 Swift 在循环
中正确识别 circle
到 PinCircleView
的类型
for case let (index, circle) as (Int, PinCircleView) in pinCirclesStackView.arrangedSubviews.enumerated() {
print(index, circle) // <- circle is PinCircleView and print's as expected
}
但是,如果我使用 is
进行类型检查,Swift 仍然只允许我访问 circle
,因为它会是 UIView
for (index, circle) in pinCirclesStackView.arrangedSubviews.enumerated() where circle is PinCircleView {
print(index, circle) // <- circle is UIView but print's PinCircleView
}
如果我理解正确,is
不会强制转换,而只会检查类型,但这让我想到了另一个问题,如果类型匹配,为什么我不能 "fully" 使用它?
Swift 类型在 编译时建立 。
在第一种情况下,case let
仅在类型为 (Int, PinCircleView)
时才将值赋给 (index, circle)
。所以在编译时,Swift 知道 circle
是 PinCircleView
类型。您可以通过 选项 -单击 circle
.
来验证这一点
for case let (index, circle) as (Int, PinCircleView) in pinCirclesStackView.arrangedSubviews.enumerated() {
print(index, circle) // <- circle is PinCircleView and print's as expected
}
在第二种情况下,(index, circle)
被分配了 arrangedSubviews.enumerated()
的每个值。在这种情况下,arrangedSubviews
returns [UIView]
和 .enumerated()
将其转换为 (Int, UIView)
元组序列。所以在这种情况下,circle
是 UIView
.
然后 where circle is PinCircleView
检查 circle
是否包含 UIView
的 PinCircleView
子类,但它不会改变 circle
类型的事实作为 UIView
。同样,使用 选项 - 单击 circle
以验证其类型为 UIView
.
for (index, circle) in pinCirclesStackView.arrangedSubviews.enumerated() where circle is PinCircleView {
print(index, circle) // <- circle is UIView but print's PinCircleView
}
在 for
内部,您知道 circle
包含 PinCircleView
,但 Swift 不包含。您可以使用 let pincircle = circle as! PinCircleView
在循环内向下转换它,并且知道它始终可以工作而不会崩溃,因为您使用 is
.
检查了它
但更好的形式是使用 for case let
版本将 circle
的类型正确地建立为 PinCircleView
。
当我使用 case let
投射视图时 Swift 在循环
circle
到 PinCircleView
的类型
for case let (index, circle) as (Int, PinCircleView) in pinCirclesStackView.arrangedSubviews.enumerated() {
print(index, circle) // <- circle is PinCircleView and print's as expected
}
但是,如果我使用 is
进行类型检查,Swift 仍然只允许我访问 circle
,因为它会是 UIView
for (index, circle) in pinCirclesStackView.arrangedSubviews.enumerated() where circle is PinCircleView {
print(index, circle) // <- circle is UIView but print's PinCircleView
}
如果我理解正确,is
不会强制转换,而只会检查类型,但这让我想到了另一个问题,如果类型匹配,为什么我不能 "fully" 使用它?
Swift 类型在 编译时建立 。
在第一种情况下,case let
仅在类型为 (Int, PinCircleView)
时才将值赋给 (index, circle)
。所以在编译时,Swift 知道 circle
是 PinCircleView
类型。您可以通过 选项 -单击 circle
.
for case let (index, circle) as (Int, PinCircleView) in pinCirclesStackView.arrangedSubviews.enumerated() {
print(index, circle) // <- circle is PinCircleView and print's as expected
}
在第二种情况下,(index, circle)
被分配了 arrangedSubviews.enumerated()
的每个值。在这种情况下,arrangedSubviews
returns [UIView]
和 .enumerated()
将其转换为 (Int, UIView)
元组序列。所以在这种情况下,circle
是 UIView
.
然后 where circle is PinCircleView
检查 circle
是否包含 UIView
的 PinCircleView
子类,但它不会改变 circle
类型的事实作为 UIView
。同样,使用 选项 - 单击 circle
以验证其类型为 UIView
.
for (index, circle) in pinCirclesStackView.arrangedSubviews.enumerated() where circle is PinCircleView {
print(index, circle) // <- circle is UIView but print's PinCircleView
}
在 for
内部,您知道 circle
包含 PinCircleView
,但 Swift 不包含。您可以使用 let pincircle = circle as! PinCircleView
在循环内向下转换它,并且知道它始终可以工作而不会崩溃,因为您使用 is
.
但更好的形式是使用 for case let
版本将 circle
的类型正确地建立为 PinCircleView
。