Swift - 用于减少 Guard 内部数组的更简洁的语法

Swift - Cleaner Syntax for Reducing an Array inside Guard

我有一个由两个数组驱动的 UIView:[Float] "data" 和 [UIColor] "colors"。如果视图没有提供正确的数据,我将显示一个空状态,由您在此处看到的 guard 语句控制:

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) { [=11=] +  }
    if total == 0 { return ([1], [UIColor.lightGray]) }

    return (data, colors)
}

我不喜欢重复使用空状态 return ([1], [UIColor.lightGray]) 两次。我试图在 guard 语句中添加 data.reduce 调用,例如:

private func unwrap() -> ([Float], [UIColor]) {
    guard
        let data = data, !data.isEmpty,
        let colors = colors, data.count == colors.count,
        data.reduce(0) { [=12=] +  } != 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) { [=13=] +  }, total != 0
        else { return ([1], [UIColor.lightGray]) } // empty state

    return (data, colors)
}

...闭包的结果 data.reduce(0) { [=17=] + } 不是可选的,因此不能包含在保护声明中。

有没有更简洁的方法来做到这一点?

想通了。

private func unwrap() -> ([Float], [UIColor]) {
    guard
        let data = data, !data.isEmpty,
        let colors = colors, data.count == colors.count,
        (data.reduce(0) { [=10=] +  }) != 0
        else { return ([1], [UIColor.lightGray]) } // empty state

    return (data, colors)
}

如何使您的 return 值成为计算变量:

private func unwrap() -> ([Float], [UIColor]) {
    var emptyVal: ([Float], [UIColor]) {
        return ([1], [UIColor.lightGray])
    }

    guard
        let data = data, !data.isEmpty,
        let colors = colors, data.count == colors.count
        else { return emptyVal } // empty state

    let total = data.reduce(0) { [=10=] +  }
    if total == 0 { return emptyVal }

    return (data, colors)
}

这是我的简化版:

private func unwrap() -> ([Float], [UIColor]) {
    guard let data = data, let colors = colors,
        data.count == colors.count, data.reduce(0, +) != 0  else {
            return ([1], [UIColor.lightGray])
    } // empty state

    return (data, colors)
}

reduce可以只用Float的+函数,空数据数组的reduce永远为0,所以不需要检查空状态。