【问题标题】:Swift can't infer conditional type in a loopSwift 无法在循环中推断条件类型
【发布时间】:2019-09-14 22:22:22
【问题描述】:

当我使用 case let 投射视图时,Swift 可以正确识别循环内 circlePinCircleView 的类型

 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 不会强制转换,而只会检查类型,但是如果类型匹配,这会引出另一个问题,为什么我不能“完全”使用它?

【问题讨论】:

  • 好吧,那是对的,但在那之后我仍然执行类型检查,它不应该对生成的元组进行操作吗?如果其中一些视图不是 PinCircleView 类型,它们将不会出现在循环 afaik 中

标签: swift casting typechecking


【解决方案1】:

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 返回[UIView].enumerated() 将其转换为(Int, UIView) 元组的序列。所以在这种情况下,circleUIView

where circle is PinCircleView 然后检查circle 是否包含PinCircleViewUIView 子类,但它不会改变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

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多