swift - swift中的协议继承和结构
问题描述
我想创建一个Validatable
具有两个属性的协议:一个validator
和一个isAbleToProceed
布尔值:
protocol Validatable {
var validator: Validator { get set }
var isAbleToProceed: Bool { get set }
}
我想定义不同类型的Validators
(出生日期验证器、电子邮件验证器等)。为此,我创建了一个工厂:
protocol Validator {}
struct ValidatorFactory {
internal static let sharedInstance = ValidatorFactory()
func dateOfBirthValidator(minimumAge: Int, maximumAge: Int) -> DateOfBirthValidator {
return DateOfBirthValidator(minimumAge: minimumAge, maximumAge: maximumAge)
}
func driversLicenseValidator(minLicenseDuration: Int) -> DriversLicenseValidator {
return DriversLicenseValidator(minLicenseDuration: minLicenseDuration)
}
}
这是 DateOfBirthValidator 的实现:
struct DateOfBirthValidator: Validator {
let minimumAge: Int
let maximumAge: Int
func isDateOfBirthValid(date: Date) -> Bool {
if let age = Calendar.current.dateComponents([.year], from: date, to: Date()).year {
return (minimumAge ... maximumAge).contains(age)
} else {
return false
}
}
}
然后我会有一个类 ViewController 来实现 Validatable 协议:
class ViewController: Validatable {
// MARK: Internal Properties
internal var validator: DriversLicenseValidator
internal var isAbleToProceed: Bool = false
}
但是编译器会报告 ViewController 不符合
Validatable
(没有验证器)
如果我创建Validator
一个超类并且所有验证器结构都变成类并从中继承,这可以解决。但是有没有办法让它与结构和协议一起工作?
解决方案
这个问题几乎与您的问题重复,除了它询问为什么不能通过协议一致性满足 get-only 属性。答案是,理论上它可以,但现在你不能。这有几个 Swift 错误
- 涵盖此问题变体的通用错误和
- 一个几乎完全是您的问题的特定错误,并作为第一个错误的副本关闭。
现在,在您的情况下,您有一个 get/set 属性(至少正如在协议中声明的那样;您let
在实现中实现了它)。
由于 Liskov 替换原则,我应该可以说:
var someValidatable = ViewController() as Validatable
someValidateable.validator = SocialSecurityValidator()
如果你能够做你想做的事,这将失败有两个原因:
validator
具有更受限制的访问权限,let
而不是var
SocialSecurityValidator
无法分配A ,validator
因为它属于类型DriversLicenseValidator
推荐阅读
- api - 如何正确设置 Curl 选项以使用 Filemaker 16-18 将多部分文件上传到 Google Drive
- python - python递归oop与功能
- maven - 如何在控制台中打印集成测试(maven failsafe)?
- sql - 休眠中的查询错误:SQL 错误:156,SQLState:S0001
- powershell - Adobe flash player powershell远程安装问题
- python - upload_blob 函数中的 Azure python asyncio 内存耗尽
- c# - C# 根据位图位置裁剪位图
- php - Woocommerce 自定义简码返回零值
- spring-boot - 无法使用带有自定义对象的地图创建实体对象
- r - 使用 name_repair 以编程方式处理重复的列