问题描述
我有关联类型的通用协议,并且在某些时候想让它不是通用的。相同的行为适用于类,但不幸的是我不能对协议使用相同的逻辑。例如,这绝对没问题:
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()