gpt4 book ai didi

swift - 如果在 Swift 中可选向下转型失败,你能继续循环吗?

转载 作者:搜寻专家 更新时间:2023-10-30 22:30:12 25 4
gpt4 key购买 nike

如果元素上的某些条件失败,继续循环是一个非常常见的习惯用法。

假设我们想对特定类型的所有 subview 做一些事情(并且,出于某种原因,不想回避类型的事情)。理想情况下,我们会写:

for view in self.subviews as [NSView] { // cast required in beta 6
if (let specificView = view as? SpecificView) == nil { // <- Error here
continue
}

// Do things at a sensible indentation level
}

上面的代码因“模式变量绑定(bind)不能出现在表达式中”而失败,如 this question .

但是,这似乎是一种常见的模式,必须在 Swift 中做到这一点。我错过了什么吗?


编辑:现在我想起来了,这似乎违反了 if let 语句的作用域规则,它只将变量作用域到内部 block 。

考虑到这一点,我想稍微扩展一下这个问题:人们通常如何在 Swift 中应用这种模式?

最佳答案

这是一个有点常见的模式,但它不是一个好的模式。我已经看到它将错误注入(inject)到 ObjC 项目中。它过多地假设了 View 层次结构,并且在更改时变得脆弱(例如,当有人为了管理旋转而注入(inject)一个您不期望的额外 View 时;真实的故事)。更好的模式是维护指向您要跟踪的 SpecificView(或 View )的属性。一般来说,向下转型是应该避免的,而不是优化的。

也就是说,它不是一个糟糕的模式,有时它是一个非常有用的模式。那么您会如何处理呢?

let specifics = self.subviews
.filter { $0 is SpecificView }
.map { $0 as SpecificView }

for view in specifics { ... }

这是一种常见的模式,所以也许我们可以将其通用化?

extension Array {
func filterByClass<T>(c: T.Type) -> [T] {
return self.filter { $0 is T }.map { $0 as T }
}
}

for view in self.subviews.filterByClass(SpecificView) { ... }

也就是说,我认为应该尽可能避免这种方法,而不是过度简化。

关于swift - 如果在 Swift 中可选向下转型失败,你能继续循环吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25486062/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com