如何通过协议继承使具有关联类型的通用协议不通用?

问题描述

我有关联类型的通用协议,并且在某些时候想让它不是通用的。相同的行为适用于类,但不幸的是我不能对协议使用相同的逻辑。例如,这绝对没问题:

class Validator<Value> {
    func validate(_ value: Value?) -> String? {
        return nil
    }
}

class StingValidator: Validator<String> {
}

class EmptyStringValidator: StingValidator {
    override func validate(_ value: String?) -> String? {
        return ((value?.isEmpty ?? true) == true) ? "Empty" : nil
    }
}

func anyfunc() {
    let validator: StingValidator = EmptyStringValidator()
}

但使用协议时出现编译错误

Protocol 'StringValidatorProtocol' 只能用作通用约束,因为它具有 Self 或关联类型要求

protocol ValidatorProtocol {
    associatedtype Value
    func validate(_ value: Value?) -> String?
}

protocol StringValidatorProtocol: ValidatorProtocol where Value == String {
}

struct EmptyStringValidator: StringValidatorProtocol {
    func validate(_ value: String?) -> String? {
        return ((value?.isEmpty ?? true) == true) ? "Empty" : nil
    }
}

func anyfunc() {
    let validator: StringValidatorProtocol = EmptyStringValidator()
}

有什么想法吗?有没有办法让通用协议不通用?我将不胜感激!

解决方法

使关联类型不泛型的协议根本不可能,我认为您需要的是更多泛型:

func anyfunc() {
    let validator: StringValidatorProtocol = EmptyStringValidator()
}

使用自由函数你不能做你想做的事,但在类或结构中:

protocol ValidatorProtocol {
    associatedtype Value
    init()
    func validate(_ value: Value?) -> String?
}

protocol StringValidatorProtocol: ValidatorProtocol where Value == String {
}

class EmptyStringValidator: StringValidatorProtocol {
    required init() {
        
    }
    func validate(_ value: String?) -> String? {
        return value?.isEmpty ?? true ? "Empty" : nil
    }
}

class MyClass<Validator: ValidatorProtocol> {
    static func validate(_ string: Validator.Value?) -> String? {
        let validator: Validator = Validator()
        return validator.validate(string)
    }
}
MyClass<EmptyStringValidator>.validate("Hello World") // nil
MyClass<EmptyStringValidator>.validate("") // "Empty"
MyClass<EmptyStringValidator>.validate(nil) // "Empty"

,

我不知道“使它不通用”是什么意思,但如果这对您来说还不够,请通过编辑告诉我们:

您显示的错误可以通过不透明常量解决。

let validator: some StringValidatorProtocol = EmptyStringValidator()

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...