Swift初学 - 四大自定义数据类型之Protocol

2019-10-13  本文已影响0人  Joshua666

最后一个自定义的类型:protocol,这个就很像java的interface,protocol只能定义property和method的名字或参数类型这些,不能有实现代码;那些遵循这个protocol的class,struct或者enum必须实现这些定义好的property(get/set)和method。

一、定义和使用

protocol Person {
    var name:String { get set }
    associatedtype IdType
    var identity: IdType { get }

    init(name: String)
    func job() -> String
}

定义了一个Person protocol,那么任何class或struct遵循Person的话,都必须要有name这个属性并且实现job这个方法:

class Student: Person {
    var name: String
    typealias IdType = String
    var identity: String = "Student Card"
    
    required init(name: String) {
        self.name = name
    }
    
    func job() -> String {
        return "\(name) is a student"
    }
}

虽然很容易理解,但有些地方还是要注意的:
a) 我在Person定义name的时候,写了get和set,说明他是一个读写的属性,在Student里,name就一定要用var不能用let
b) 如果遵循的protocol里有init,那么实现的时候必须要用required init
c) protocol中的identity虽然逻辑有点牵强,但associatedtype就是为了在protocol中先声明一个自定义的类型(IdType),因为我们并不知道以后遵循这个protocol的identity是string还是Int还是什么;然后再Student的实现里我们就可以先用typealias把IdType明确为String,然后在给identity赋值

二、用extension来遵循protocol

如果我们想让第三方库中的一个class或struct也遵循我们定义的protocol,我们可以用extension来实现:

protocol MyString {
    var length: Int { get }
}

extension String: MyString {
    var length: Int {
        return self.count
    }
}

let str = "sdfsdfsd"
str.length // 8

三、一些常用的swift protocols

Swift中有很多protocols,我们为了自己方便,可以让自己的class或struct来遵循他们,下面就列举几个:

1、Equatable

我们知道两个class是不能用==好来比较的,但是我就是想用==号来比较他们一些属性,这样很方便。怎么实现呢?

extension Student: Equatable {
    static func == (lhs: Student, rhs: Student) -> Bool {
        return lhs.name == rhs.name
    }
}
let me = Student(name: "joshua")
let you = Student(name: "dog")
let he = Student(name: "dasfsdfsd")
me == you //false

a) 你可以不用extension,直接在定义Student的时候就让他遵循Equatable;但是用extension更容易管理代码,哪天你不想遵循了,就删了这几行就行
b) 在xcode写下: Equatable,点一下Fix,他会自动给你补全==这个func的

2、Comparable

extension Student: Comparable {
    static func < (lhs: Student, rhs: Student) -> Bool {
        return lhs.name.count < rhs.name.count
    }
}
me < you // false

有了Equatable和Comparable,swift有时候就可以自动比较Student这个类型了,比如

var arr = [me, you, he]
arr.sort() // [you, me, he]

非常方便!

3、Hashable

只有像String, Int这种struct才能当做dictionary的key,如果你想让class类型也能当key,那你就得遵循Hashable:

extension Student: Hashable {
    static func == (lhs: Student, rhs: Student) -> Bool {
        return lhs.name == rhs.name
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(name)
    }
}
var dict = [me: 1]

a) 如果我们已经遵循了Equatable,==这个func不写也行
b) hash这个func xcode好像不会帮你补全,你得自己写
c) hasher必须combine所有你在==号里包括的属性

4、CustomStringConvertible

这个可以用来debug:

extension Student: CustomStringConvertible {
    var description: String {
        return "My name is \(name)"
    }
}
print(me) // My name is joshua
上一篇 下一篇

猜你喜欢

热点阅读