Swift 以associatedtype为参数类型的协议

Swift protocol with associatedtype as a parameter type

所以我有这个协议

public protocol UseCase {

    associatedtype ResponseType
    associatedtype Parameters

    func build(params: Parameters) -> Single<ResponseType>

}

public extension UseCase {

    func execute(params: Parameters) -> Single<ResponseType> {
        return build(params: params)
                .subscribeOn(ConcurrentDispatchQueueScheduler(qos: DispatchQoS.background))
                .observeOn(MainScheduler.instance)
    }

}

我有一个实现 UseCase 协议的结构,像这样

public struct CreateNewAccount: UseCase {

    private let repository: AuthRepository

    public init(repository: AuthRepository) {
        self.repository = repository
    }

    public func build(params: Params) -> Single<User> {
        return repository.register(params: params)
    }

    public struct Params: RequestParams {
        ...
    }
}

我想在另一个 class 上使用这个 CreateNewAccount,但我不想直接使用 CreateNewAccount,我想将它作为 UseCase 传递] 相反,因为它是一个协议 它可以很容易地被模拟以进行测试。 但是当我做这样的事情时

class RegisterViewModel: ViewModel {

    private let createNewAccount: UseCase // Error on this line

    init(createNewAccount: UseCase) { // Error on this line
        self.createNewAccount = createNewAccount
    }
}

这给了我这样的错误

Error:(34, 35) protocol 'UseCase' can only be used as a generic constraint because it has Self or associated type requirements

那么,我可以从我的代码中更改某些内容来使这种情况有效吗?提前致谢。

您不能将关联类型的协议用作字段。

您只能将它们用作 类 的实现。在大多数情况下,那些 类 应该是通用的。

例如,允许使用以下代码:

public struct CreateNewAccount<T, K>: UseCase {

    public typealias ResponseType = T

    public typealias Parameters = K
}

等等,

private let createNewAccount: CreateNewAccount<YouClass1,YouClass2>

或者用另一种协议以某种方式包装它。