已验证 3.0.0

Validated 3.0.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布时间最近发布2016年10月
SPM支持SPM

Benjamin Encz 维护。



Validated 3.0.0

Validated

Validated是一个小型的μ库(~50行代码),通过提供用于轻松生成具有内置保证的新类型的工具,允许您更好地利用Swift的类型系统。

Validated允许您使用类型系统来验证值的属性,提供编译时保证的新层次。

使用验证器,您可以定义新的类型,这些类型向现有类型添加保证

// Create a new string type that can never be empty
typealias NonEmptyString = Validated<String, NonEmptyStringValidator>

示例

您可能有一个函数只擅长处理当用户已登录时的User值。通常,您会在代码中实现此要求并添加文档,但您没有简单的方法来在类型签名中表达此不变性

/// Please ever only call with a logged-in user!
func performTaskWithUser(user: User) {
    precondition(
        user.loggedIn, 
        "It is illegal to call this method with a logged out user!"
    )

    // ...
}

使用Validated,您可以快速创建一个新的类型来描述类型系统中的此要求。这使得无法用未登录用户调用该函数,并使得方法签名表达出您的不变性(而不是依赖于文档)

func performTaskWithUser(user: LoggedInUser) {
    // ...
}

那么这个新的LoggedInUser类型是如何创建的呢?

首先,您需要实现一个验证器

struct LoggedInValidator: Validator {

    static func validate(value: User) -> Bool {
        return value.loggedIn
    }

}

一个Validator需要实现一个validate函数,该函数接受此验证器可以验证的类型(在这种情况下是User)。该函数返回一个Bool。如果满足要求则返回true,否则返回false

有了Validator,我们可以这样创建我们的新类型:

typealias LoggedInUser = Validated<User, LoggedInValidator>

请注意,不需要提供typealias,但对于大多数情况,这是推荐的。

就这样!

LoggedInUser现在有一个失败的初始化器,它接受一个User。如果传入的User满足已登录的要求,则您将拥有一个LoggedInUser,否则为nil。此外,LoggedInUser还提供了一个抛出初始器的功能,以便您可以选择将失败验证当作错误来处理,而不是nil值。

底层值(完整的User值)存储在LoggedInUser.value属性中。

基础知识之外

Validated提供了一些可能不是那么显而易见的额外功能。

使用逻辑运算符组合验证器

Validated 提供了 Validator 类型,用于逻辑操作,允许您以不同的组合要求多个验证。例如,您可以使用 And 验证器要求必须满足两个条件才能初始化您的类型。

typealias AllCapsNonEmptyString =
            Validated<String, And<NonEmptyStringValidator, AllCapsLatinStringValidator>>

OrNot 也作为辅助验证器提供。您可以查看规范以获取更多示例。

泛型验证器

Validator 本身可以是泛型的。如果您想对整个类型类别提供验证,这非常有用。示例验证器 NonEmptyCollectionValidator 通过使用泛型要求可以应用于所有验证器类型。

struct NonEmptyCollectionValidator<T: CollectionType>: Validator {
    static func validate(value: T) -> Bool {
        if !value.isEmpty {
            return true
        } else {
            return false
        }
    }
}

但是,当使用此验证器创建类型时,您必须指定要验证的确切集合类型。

typealias NonEmptyListOfStrings = Validated<[String], NonEmptyCollectionValidator<[String]>>

这个库是否支持依赖类型?

不是真正意义上的。依赖类型使我们能够仅基于值来定义类型。该库仅允许我们根据值和验证器验证一个类型是否为指定类型 <T>。值本身并不会改变类型信息。

真正的依赖类型会产生以下结果:

[1, 2, 3] // type = Array<count:3 type:Int>
[1, 2, 3, 4] // type = Array<count:4 type:Int>

使用 Validated,我们只能验证一个类型是否属于我们静态定义的某个类别。

ListOf3([1,2,3]) // type = ListOf3<Array<Int>
ListOf3([1,2,3,4]) // type = nil

然而,这些静态提供的检查仍然可以为您的代码增加很多价值;请参见上面的示例。

安装

Validated 通过常规方式提供。

取得联系

如果您有任何问题,您可以在twitter上找到我 @benjaminencz