跟戴铭学iOS编程:理顺核心知识点
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.2.1 类型约束

HTN项目里状态机的Transition结构体的定义,如下所示。

struct HTNTransition<S: Hashable, E: Hashable> {
    let event: E
    let fromState: S
    let toState: S
         
    init(event: E, fromState: S, toState: S) {
        self.event = event
        self.fromState = fromState
        self.toState = toState
        if fromState == toState {
            print("Two state is same")
        }
    }
}

以上示例中的event、fromState和toState可以是不同类型的数据,也可以是枚举、字符串或者整数等。定义S和E两个不同的泛型可以让状态和事件的类型不同,这样接口会更加灵活,更容易适配更多的项目。

大家可以注意到S和E都遵循Hashable协议,这就是要求它们要符合这个协议的类型约束。使用协议可以使这两个泛型更加规范和易于扩展。

在Swift中,String、Int、Double、Bool,以及无关联值的枚举等都是遵循Hashable协议的。Hashable协议提供的hashValue方法用于判断协议对象是否相等。

Hashable协议同时也是继承Equatable协议的,遵循了Hashable协议的类或结构通过实现Equatable协议确定自定义的类或结构是否相同。在遵循了Equatable协议后,协议里的函数就可以对遵循了这个协议的参数进行是否相等的比较了。Swift的内置类型都支持Equatable协议,比如String、Int和Float等都支持==或!=运算。注意,自定义的类型如果没有遵循Equatable协议是没法使用==运算或者使用与这个运算相关的方法的,比如数组里的contain等。自定义类型一旦实现了Equatable协议也就意味着能够使用系统集合里的API进行查找,通过重载>、<、>=和<=等,还能够对自定义的类型在集合里进行排序。