iOS学习笔记之Swift中常见的协议

前言

Swift标准库为我们提供了55中协议,基本都是以TypeableConvertible结尾的。

Type结尾的协议,表示可以被当作某种类型;

able结尾的协议,表示具备某种能力或者特性;

Convertible结尾的协议,表示能够进行改变或者变化。

Swift标准库中的55个协议

AbsoluteValuable
AnyCollectionType,
AnyObject
ArrayLiteralConvertible
BidirectionalIndexType
BitwiseOperationsType
BooleanLiteralConvertible
BooleanType
CVarArgType
CollectionType
Comparable
CustomDebugStringConvertible
CustomLeafReflectable
CustomPlaygroundQuickLookable
CustomReflectable
CustomStringConvertible
DictionaryLiteralConvertible
Equatable
ErrorType
ExtendedGraphemeClusterLiteralConvertible
FloatLiteralConvertible
FloatingPointType
ForwardIndexType
Generator Type
Hashable
Indexable
IntegerArithmeticType
IntegerLiteralConvertible
IntegerType
IntervalType
LazyCollectionType
LazySequenceType
MirrorPathType
MutableCollectionType
MutableIndexable
MutableSliceable
NilLiteralConvertible
OptionType
OutputStreamType
RandomAccessIndexType
RangeReplaceableCollectionType
RawRepresentable
ReverseIndexType
SequenceType => Sequence
SetAlgebraType
SignedIntegerType
SignedNumberType
Streamable
Strideable
StringInterpolationConvertible
StringLiteralConvertible
UnicodeCodecType
UnicodeScalarLiteralConvertible
UnsignedIntegerType

常见的协议

Equatable

Equatable比较相关的协议,遵循该协议表示实例能够用于做相等的比较,但是需要重载==运算符。

struct Person: Equatable {
    var name: String
    var age: Int
    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name && lhs.age == rhs.age
    }
}

Hashable

哈希表是一种基础的数据结构。Swift中字典由两种泛型类型组成,其中Key必须实现Hashable协议。

public protocol Hashable : Equatable {
    var hashValue: Int { get }
    func hash(into hasher: inout Hasher)
}

通过以上源码可以看出Hashable是遵循了Equable

Comparable

Comparable是基于Equatable的一种延续,同样用于比较相关的协议,遵循该协议的实例能够进行比较,但是需要重载<运算符。

struct Person: Comparable {
    var name: String
    var age: Int
    static func < (lhs: Person, rhs: Person) -> Bool {
        return lhs.age < rhs.age
    }
}

CustomStringConvertible

CustomStringConvertible提供了一种用文本表示一个对象或者结构的描述的方式,可以在任何遵循该协议的类型中自定义结构的文本,但是一定需要覆盖description的属性。

struct Person: CustomStringConvertible {
    var name: String
    var age: Int
    var description: String {
        return "\(name)" + "的年龄是" + "\(age)"
    }
}

ExpressibleByArrayLiteral

ExpressibleByArrayLiteral提供了使用数组文本初始化的类型的能力,具体就是使用逗号分割的值、实例、字面值列表

struct Person: ExpressibleByArrayLiteral {
    typealias ArrayLiteralElement = Any
    
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    init(arrayLiteral elements: Person.ArrayLiteralElement...) {
        var name: String = ""
        if let nm = elements.first as? String {
            name = nm
        }
        var year: Int = 0
        if let aage = elements[1] as? Int {
            year = aage
        }
        self.init(name: name, age: year)
    }
}

使用协议的好处

协议可以当作类型使用

苹果在Swift中提出协议可以作为一种类型,并且在官方文档中还为开发者具体指出了可以将协议当作类型使用的具体场景:

  • 作为常量、变量或者属性的类型
  • 作为数组、字典或者其他存储器的元素类型
  • 在函数、方法或者初始化容器里作为形参或者返回类型

你可能感兴趣的:(iOS学习笔记之Swift中常见的协议)