美文网首页有些文章不一定是为了上首页投稿
100 Days of SwiftUI —— Day 11:协议

100 Days of SwiftUI —— Day 11:协议

作者: 韦弦Zhy | 来源:发表于2020-03-13 21:02 被阅读0次

    \color{red}{\Huge \mathtt{100 \ Days \ of \ SwiftUI \ — \ Day \ 11}}

    \color{orange}{\Large \mathbf{协议和扩展}}

    \underline{\color{orange}{\large \mathit{Protocols \ and \ Extensions}}}

    今天,您将学习一些真正的Swifty功能:协议和面向协议的编程(protocol-oriented programming —— POP)。

    POP消除了大型复杂的继承层次结构,并用可以组合在一起的更小更简单的协议代替了它们。这确实是托尼·霍尔(Tony Hoare)多年前说过话的实现:“在每个大的程序中,都有一个小程序试图跳出来。(inside every large program, there is a small program trying to get out)”

    您将使用第一个SwiftUI项目中的协议,它们将在您的整个Swift编码生涯中继续发挥着不可估量的作用——值得花时间来熟悉它们。

    今天,您有6个一分钟的视频可供观看,并且您将了解协议扩展以及两者的结合:协议扩展。观看完每个视频后,我们会进行一次简短的测试,以帮助您了解所教的内容。

    1. 协议 Protocolstest

    协议是描述某些事物必须具有的属性和方法的一种方式。然后,您可以告诉Swift哪些类型使用该协议,该过程称为采用或遵循协议。

    例如,我们可以编写一个函数来接受具有id属性的内容,但是我们并不在乎使用哪种类型的数据。我们将首先创建一个Identifiable协议,该协议要求所有遵循协议的类型都具有一个可以读取(“get”)或写入(“set”)的id字符串:

    protocol Identifiable {
        var id: String { get set }
    }
    

    我们无法创建该协议的实例——它是对所需内容的描述,而不是我们可以直接创建和使用的内容。但是我们可以创建一个遵循它的结构体:

    struct User: Identifiable {
        var id: String
    }
    

    最后,我们将编写一个displayID()函数,该函数接受任何遵循Identifiable协议的对象,比如上面的User

    func displayID(thing: Identifiable) {
        print("My ID is \(thing.id)")
    }
    

    2. 协议继承 Protocol inheritancetest

    一个协议可以在称为协议继承的过程中从另一个协议继承。与类不同,在顶部添加自己的自定义项之前,您可以同时从多个协议继承

    我们将定义三个协议:Payable需要采用的类型来实现calculateWages()方法,NeedsTraining需要采用的类型实现study()方法,然后HasVacation需要采用的类型来实现takeVacation()方法:

    protocol Payable {
        func calculateWages() -> Int
    }
    
    protocol NeedsTraining {
        func study()
    }
    
    protocol HasVacation {
        func takeVacation(days: Int)
    }
    

    现在,我们可以创建一个Employee协议,将它们集成到一个协议中。我们可以不需要在上面添加任何内容,因此我们只需要写大括号即可:

    protocol Employee: Payable, NeedsTraining, HasVacation { }
    

    现在,我们可以使新类型遵循该单一协议,而不是三个单独协议中的每一个。

    3. 扩展 Extensionstest

    扩展允许您将方法添加到现有类型中,以使它们执行原本没有设计要执行的操作。

    例如,我们可以向Int类型添加一个扩展,以便它具有一个squared()方法,该方法返回当前数字乘以自身的值:

    extension Int {
        func squared() -> Int {
            return self * self
        }
    }
    

    要尝试该方法,只需创建一个整数,您将看到它现在具有squared()方法:

    let number = 8
    number.squared()
    

    Swift不允许您在扩展中添加存储属性,因此必须改用计算属性。例如,我们可以向整数添加一个新的isEven计算属性,如果该属性包含偶数则返回true:

    extension Int {
        var isEven: Bool {
            return self % 2 == 0
        }
    }
    

    4. 协议扩展 Protocol extensionstest

    协议可让您描述遵循协议的类或结构体需要有的方法,但不提供内部代码。扩展使您可以在方法内部提供代码,但仅影响一种数据类型——您不能同时将方法添加到许多类型中。

    协议扩展同时解决了这两个问题:它们像常规扩展一样,只是扩展了整个协议,以便所有符合条件的类型都可以进行更改,而不是像Int这样扩展特定类型。

    例如,这是一个数组和一个包含一些名称的集合:

    let pythons = ["Eric", "Graham", "John", "Michael", "Terry", "Terry"]
    let beatles = Set(["John", "Paul", "George", "Ringo"])
    

    Swift的数组和集合均符合称为Collection的协议,因此我们可以对该协议编写一个扩展,以添加summary()方法来整齐地打印集合:

    extension Collection {
        func summarize() {
            print("There are \(count) of us:")
    
            for name in self {
                print(name)
            }
        }
    }
    

    ArraySet现在都将具有该方法,因此我们可以尝试一下:

    pythons.summarize()
    beatles.summarize()
    

    5. 面向协议编程 Protocol-oriented programmingtest

    协议扩展可以为我们自己的协议方法提供默认实现。这使类型很容易符合协议,并允许使用一种称为“面向协议编程(POP)”的技术——围绕协议和协议扩展来编写代码。

    首先,这是一个称为Identifiable的协议,该协议要求任何符合条件的类型都具有id属性和identify()方法:

    protocol Identifiable {
        var id: String { get set }
        func identify()
    }
    

    我们可以使每个采用此协议的类型都编写自己的identify()方法,但是协议扩展允许我们提供默认值:

    extension Identifiable {
        func identify() {
            print("My ID is \(id).")
        }
    }
    

    现在,当我们创建一个符合Identifiable的类型时,它将自动获得identify()

    struct User: Identifiable {
        var id: String
    }
    
    let twostraws = User(id: "twostraws")
    twostraws.identify()
    
    

    6. 协议和扩展:总结 Protocols and extensions summarytest

    您已经完成了本系列第九部分,所以让我们总结一下:

    1、协议描述了采用的类型必须具有的方法和属性,但未提供这些方法的实现。
    2、您可以在其他协议的基础之上构建协议,类似于类。
    3、扩展使您可以向特定类型(例如Int)添加方法和计算属性。
    4、协议扩展使您可以向协议添加方法和计算属性。
    5、面向协议编程是一种将应用程序体系结构设计为一系列协议,然后使用协议扩展来提供默认方法实现的实践。

    ≧◔◡◔≦

    < Previous: 类 \color{orange}{\large \Bbb{100 \ Days \ of \ SwiftUI}} Next: 协议和扩展>

    相关文章

      网友评论

        本文标题:100 Days of SwiftUI —— Day 11:协议

        本文链接:https://www.haomeiwen.com/subject/mxohjhtx.html