带有类型化的 Swift 协议(protocol)。协议(protocol)只能用作通用约束

标签 swift protocols factory swift-protocols

我在考虑我的应用程序中的验证检查,我认为在任何模型上调用 ValidatorFactory,实现 Validee,这意味着说哪个类负责 ValidatorCreation 听起来不错。但是下面的代码不起作用:(

代码:

struct Client: Validee {
    typealias ValidatorFactoryClass = ClientValidator
}

protocol Validee {
    associatedtype ValidatorFactoryClass: AbstractValidatorFactory
}

protocol Validator {
    func validate() throws -> Void
}

protocol AbstractValidatorFactory {
    associatedtype Model
    static func create(fromModel model: Model) -> Validator
}

struct ValidatorFactory {
    static func createValidator(fromModel model: Validee) -> Validator {
        return model.ValidatorFactoryClass.create(fromModel: model)
    }
}

struct ClientValidator : AbstractValidatorFactory {
    typealias Model = Client

    static func create(fromModel model: Model) -> Validator {
        return ClientDeliveryAddressValidator(withModel: model)
    }
}

struct ClientDeliveryAddressValidator: Validator {
    typealias Model = Client
    let client: Client

    init(withModel client: Client) {
        self.client = client
    }

    func validate() throws {

    }
}

let client = Client()
do {
    try ValidatorFactory.createValidator(fromModel: client).validate()
} catch {
    // error handling here
}

但即使我忘记了 Validator Factory 并尝试运行以下代码,它也不起作用:

client.ValidatorFactoryClass.create(fromModel: client)

为什么?

最佳答案

如果您遇到的问题是由于编译错误,则您的 ValidatorFactory 结构需要修改。

您不能直接将协议(protocol)用作类型。您将它用作类型的约束。这意味着不是将 Validee 作为 ValidatorFactory.createValidator 的参数类型,而是对该类型的约束。这种变化会给你:

struct ValidatorFactory<T:Validee> {
    static func createValidator(fromModel model: T) -> Validator {
        return model.ValidatorFactoryClass.create(fromModel: model)
    }
}

这仍然有一个问题,因为 Swift 无法计算出类型 T 和调用 create 的参数类型之间的关系。但是这种关系存在于您的代码中;您只需要明确说明即可。

ValidatorFactory 更改为此为我编译。但是,我没有尝试运行代码。

struct ValidatorFactory<T:Validee> {
    static func createValidator(fromModel model: T) -> Validator {
        return T.ValidatorFactoryClass.create(fromModel: model as! T.ValidatorFactoryClass.Model)
    }
}

编辑:

鉴于 Validee 已经知道工厂,更改设计以便 Validee 知道直接创建 Validator 会更简单。

这会给你:

protocol Validee {
    static func create(fromModel model: Self) -> Validator
}

protocol Validator {
    func validate() throws -> Void
}

struct ValidatorFactory<T:Validee> {
    static func createValidator(fromModel model: T) -> Validator {
        return T.create(fromModel: model)
    }
}

struct Client: Validee {
    static func create(fromModel model: Client) -> Validator {
        return ClientDeliveryAddressValidator(withModel: model)
    }
}

struct ClientDeliveryAddressValidator: Validator {
    typealias Model = Client
    let client: Client

    init(withModel client: Client) {
        self.client = client
    }

    func validate() throws {

    }
}

关于带有类型化的 Swift 协议(protocol)。协议(protocol)只能用作通用约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42755297/

相关文章:

swift - 在非转义闭包中包含(或不包含)捕获列表有什么区别?

arrays - 对实现 Equatable 的结构数组的操作

c# - 使用枚举和继承的工厂设计模式

java - 使用FactoryBean初始化的Bean接收FactoryBean而不是它创建的Obect

ios - 我可以快速支持协议(protocol)的多重继承吗?

java - 如何为需要 MyClass.class 参数的工厂方法注入(inject) Spring Bean

swift - 如何使用 Combine 跟踪 UIViewRepresentable 类中的 UITextField 更改?

swift - 在多个 UICollectionViewCell 之间传递数据

iphone - 判断一个类在运行时是否符合特定的协议(protocol)方法?

swift - 协议(protocol)对保留计数有影响吗?