协议继承和结构迅速

时间:2019-04-05 06:47:58

标签: swift struct

我想创建一个具有两个属性的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成为超类并且所有验证器结构都变为类并从中继承,则可以解决此问题。但是有办法使它与结构和协议一起工作吗?

1 个答案:

答案 0 :(得分:2)

This question几乎是您的副本,只是它询问为什么不能通过协议一致性来满足仅获取属性。答案是,理论上可以,但是现在您不能。上面有几个Swift错误

  • A generic bug涵盖了该问题的变体,并且
  • A specific bug,这几乎是您的问题,已作为第一个问题的副本被关闭。

现在,在您的情况下,您具有get / set属性(至少按照协议中的声明;您在实现中将其设置为let)。

由于Liskov替代原则,我应该可以说:

var someValidatable = ViewController() as Validatable
someValidateable.validator = SocialSecurityValidator()

如果您能够做自己想做的事,则失败的原因有两个:

  1. validator的访问权限受到限制,并且是let而不是var
  2. 无法将SocialSecurityValidator分配给validator,因为它的类型为DriversLicenseValidator