嵌套泛型类型的扩展

时间:2018-01-25 23:00:37

标签: swift generics

我有一个简单的结果类型:

enum Result<ValueType> {
    case success(ValueType)
    case failure(Error)
}

我想在结果数组和可选结果数组上创建一个函数,将所有结果合并为一个结果。但是,我正在努力想办法表达这一点。这就是我想要做的事情:

extension Array<Optional<Result<ValueType>>> {
    func combined() -> Result<[ValueType]>? {
        var values: [ValueType] = []
        for result in self {
            switch result {
                case .success(let value)?:
                    values.append(value)
                case .failure(let error)?:
                    return .failure(error)
                case .none:
                    return nil
            }
        }
        return .success(values)
    }
}

这显然无法编译。但有没有办法真正表达这个?

1 个答案:

答案 0 :(得分:5)

您可以简单地使用泛型类型约束使combined函数泛型,而不是使整个扩展通用。

extension Array {
    func combined<ValueType>() -> Result<[ValueType]>? where Array.Element == Optional<Result<ValueType>> {
        var values: [ValueType] = []
        for result in self {
            switch result {
            case .success(let value)?:
                values.append(value)
            case .failure(let error)?:
                return .failure(error)
            case .none:
                return nil
            }
        }
        return .success(values)
    }
}

结果:

let optionalResults: [Result<Int>?] = [Result.success(1),Result.success(2)]
optionalResults.combined() //success([1,2])
let strings = ["a","b"]
strings.combined() //doesn't compile
let ints = [1,2]
ints.combined() //doesn't compile