【发布时间】:2017-12-31 15:49:16
【问题描述】:
我有一个由两个数组驱动的 UIView:[Float]“数据”和[UIColor]“颜色”。如果视图没有提供正确的数据,我将显示一个空状态,由您在此处看到的保护语句控制:
private func unwrap() -> ([Float], [UIColor]) {
guard
let data = data, !data.isEmpty,
let colors = colors, data.count == colors.count
else { return ([1], [UIColor.lightGray]) } // empty state
let total = data.reduce(0) { $0 + $1 }
if total == 0 { return ([1], [UIColor.lightGray]) }
return (data, colors)
}
我不喜欢重复使用空状态return ([1], [UIColor.lightGray]) 两次。我尝试在保护语句中添加 data.reduce 调用,例如:
private func unwrap() -> ([Float], [UIColor]) {
guard
let data = data, !data.isEmpty,
let colors = colors, data.count == colors.count,
data.reduce(0) { $0 + $1 } != 0
else { return ([1], [UIColor.lightGray]) } // empty state
return (data, colors)
}
...编译器不理解语法
private func unwrap() -> ([Float], [UIColor]) {
guard
let data = data, !data.isEmpty,
let colors = colors, data.count == colors.count,
let total = data.reduce(0) { $0 + $1 }, total != 0
else { return ([1], [UIColor.lightGray]) } // empty state
return (data, colors)
}
...闭包data.reduce(0) { $0 + $1 } 的结果不是可选的,因此不能包含在保护声明中。
有没有更简洁的方法来做到这一点?
【问题讨论】:
-
避免使用并行数组;创建一个包含
Float和UIColor的struct,然后拥有该结构的数组。这样你的data.count == colors.count前置条件就会消失,因为它现在由编译器强制执行。 -
@Hamish 确实如此。这是一个 XY 问题。
-
在这个 UIView 实现的类中,从源数组创建一个结构是不必要的开销,没有任何好处。使实现更复杂,更不优雅。