首页 > 解决方案 > 使用通用协议作为接口

问题描述

我想创建一个UseCase协议,使用通用协议。然后我想为所有实现创建一个接口,以便为测试创建模拟。

这是我到目前为止所做的:

struct Product {}

protocol UseCase {
    associatedtype ReturnType
    associatedtype Param
    func execute(_ params: Param, completion: ((ReturnType) -> Void))
}


protocol FetchProductsUseCase: UseCase {
    associatedtype ReturnType = [Product]
    associatedtype Param = Void
}


struct FetchProductsUseCaseImpl: FetchProductsUseCase {
    func execute(_ params: Param , completion: ((ReturnType) -> Void)) {
        completion([])
    }
}

//ERROR: Protocol 'FetchProductsUseCase' can only be used as a generic constraint because it has Self or associated type requirements
var useCase: FetchProductsUseCase!

有人可以帮我解决这个问题吗?

我搜索了 SOF,发现了多个关于泛型的主题,但没有一个对我的案例有帮助。

标签: iosswift

解决方案


所以没有办法“限制” FetchProductUse 案例只接受一对 Generics ?(即:无效/[产品])?

是的,但你FetchProductsUseCase不是你的做法。改为这样做:

struct AnyUseCase<P, R>: UseCase {

    typealias ReturnType = R
    typealias Param = P

    init<U>(useCase: U) where U: UseCase, U.ReturnType == ReturnType, U.Param == Param {
        _execute = useCase.execute
    }

    func execute(_ params: P, completion: ((R) -> Void)) {
        _execute(params, completion)
    }

    let _execute: (P, (R) -> Void) -> Void
}

var useCase: AnyUseCase<Void, [Product]>!

然后您可以执行以下操作:

useCase = AnyUseCase(useCase: FetchProductsUseCaseImpl())

我认为你的下一个错误将completion是没有逃避。它可能需要。


推荐阅读