嵌套泛型类型的扩展

Dag*_*ren 0 generics swift

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

enum Result<ValueType> {
    case success(ValueType)
    case failure(Error)
}
Run Code Online (Sandbox Code Playgroud)

我想在结果数组和可选结果数组上创建一个函数,以将所有结果合并为一个。但是,我正在竭尽全力想出一种表达方式。这就是我想做的:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

这显然无法编译。但是有没有一种方法可以真正表达这一点?

Dáv*_*tor 6

您可以简单地使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)
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

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
Run Code Online (Sandbox Code Playgroud)